Object Pascal has the concept of Forward declarations. Objective-C takes this concept a bit
further: it allows to declare a class which is defined in another unit. This has been dubbed ’Formal
declaration’ in Objective-Pascal. Looking at the syntax diagram, the following is a valid
declaration:
MyExternalClass = objcclass external;
This is a formal declaration. It tells the compiler that MyExternalClass is an Objective-C class
type, but that there is no declaration of the class members. The type can be used in the remainder
of the unit, but its use is restricted to storage allocation (in a field or method parameter definition)
and assignment (much like a pointer).
As soon as the class definition is encountered, the compiler can enforce type compatibility.
The following unit uses a formal declaration:
unit ContainerClass;
{$mode objfpc}
{$modeswitch objectivec1}
interface
type
MyItemClass = objcclass external;
MyContainerClass = objcclass
private
item: MyItemClass;
public
function getItem: MyItemClass; message ’getItem’;
end;
implementation
function MyContainerClass.getItem: MyItemClass;
begin
result:=item; // Assignment is OK.
end;
end.
A second unit can contain the actual class declaration:
unit ItemClass;
{$mode objfpc}
{$modeswitch objectivec1}
interface
type
MyItemClass = objcclass(NSObject)
private
content : longint;
public
function initWithContent(c: longint): MyItemClass;
message ’initWithContent:’;
function getContent: longint;
message ’getContent’;
end;
implementation
function MyItemClass.initWithContent(c: longint):
MyItemClass;
begin
content:=c;
result:=self;
end;
function MyItemClass.getContent: longint;
begin
result:=content;
end;
end.
If both units are used in a program, the compiler knows what the class is and can verify the
correctness of some assignments:
Program test;
{$mode objfpc}
{$modeswitch objectivec1}
uses
ItemClass, ContainerClass;
var
c: MyContainerClass;
l: longint;
begin
c:=MyContainerClass.alloc.init;
l:=c.getItem.getContent;
end.