정식 선언

정식 선언 (Formal declaration)

Object Pascal에는 전방 선언(Forward declaration)이라는 개념이 있어요. Objective-C는 이 개념을 한 발 더 나아가, 다른 유닛에 정의된 클래스를 선언만 해 두는 걸 허용하는데, 이걸 Objective-Pascal에서 "정식 선언(Formal declaration)"이라고 불러요. 문법 다이어그램을 보면 다음이 유효한 선언이에요.

출처: Free Pascal Reference - Formal declaration

본문

MyExternalClass = objcclass external;

이게 정식 선언이에요. 컴파일러에게 MyExternalClass가 Objective-C 클래스 타입이지만, 클래스 멤버에 대한 선언은 없다는 걸 알려줘요. 이 타입은 해당 유닛의 나머지 부분에서 사용할 수 있지만, 그 용도가 저장 공간 할당(필드나 메서드 매개변수 정의)과 대입(assignment)으로 제한돼요. 포인터처럼 취급되는 거죠.

실제 클래스 정의가 등장하는 순간부터 컴파일러는 타입 호환성을 검증할 수 있게 돼요.

정식 선언을 사용하는 유닛을 볼게요.

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.

그리고 다른 유닛이 실제 클래스 선언을 담을 수 있어요.

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.

두 유닛을 프로그램에서 함께 사용하면, 컴파일러는 클래스가 무엇인지 알고 일부 대입의 정확성을 검증할 수 있어요.

Program test;

{$mode objfpc}
{$modeswitch objectivec1}

uses
  ItemClass, ContainerClass;

var
  c: MyContainerClass;
  l: longint;
begin
  c:=MyContainerClass.alloc.init;
  l:=c.getItem.getContent;
end.

더 알아보기

  • 정식 선언은 Objective-C 클래스 선언(11.2절)에서 다루는 objcclass 문법 위에서 동작해요.
  • objectivec1 모드 스위치가 이 기능의 전제 조건이에요.