高見龍

iOS app/Ruby/Rails Developer & Instructor, 喜愛非主流的新玩具 :)

@class directive in Objective-C

前面幾篇有提到了在Objective-C裡的OOP要怎麼寫,也知道要怎麼在@interface裡設定instance variable(以下簡稱ivar),雖然範例程式碼裡只是用了int這個簡單型態,但實際上更常看到的是在A類別裡有放一個B類別的物件的情況(Composition)。通常你如果要用到一個A類別的時候,你會用:

1
#import "A.h"

的方法把header檔給import裡來,但是來假想一下下面這個情境:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// A類別裡有放了一顆B ivar
@interface A : NSObject
{
  B *b;
}

@end

@implementation A
@end

// B類別裡有放了一顆A ivar
@interface B : NSObject
{
  A *a;
}
@end

@implementation B
@end

當然舉這個例子是比較極端啦,這樣的情況應該很少發生。如果你跑一下以上的的程式碼,會得到錯誤訊息”expected specifier-qualifier-list before ‘B’”,意思就是說這個B類別並不存在。A跟B兩個類別互相有需要,但B還沒出生,變成是雞生蛋蛋生雞的問題,這時候就可以用上@class這個語法了。只要在@interface A前面加一行:

1
@class B;

這行就是告訴編譯器說「這個B是一個類別,至於這個B類別的內容你不用管,反正遲早會告訴你,你先用就是了」,這樣一來就可以順利通過編譯了。不過寫了@class不代表就可以不用實作那個類別的內容,如果到時候沒有import B的header進來或是沒有實作B類別,硬是要用的話在編譯過程就會跳出一個訊息”warning: receiver ‘B’ is a forward class and corresponding @interface may not exist”。

優點:

  1. 跟#import語法比起來,用@class的編譯速度比較快。
  2. 可解決互相參照的問題。

缺點:

其實我也不知道這樣會有什麼缺點

Comments