#import の使いどころ:循環参照しないために。
!注意!
この内容はあまり正しくありません。Objective-Cの循環参照についてとして、書き直しました。こちらを参照ください。
Objective-C を書いていてたまに出会うのが、循環参照の問題。
error: expected specifier-qualifier-list before 'MyClass'
循環参照していると、こののように定義が無い、という旨のエラーが出る。
ClassA と ClassB という二つのクラスがあるとする。それぞれ相互にヘッダの中で import すると、この循環参照が発生する。
[ClassA.h] #import "ClassB.h" @interface ClassA { ClassB variableB; } @end
[ClassB.h] #import "ClassA.h" @interface ClassB { ClassA variableA; } @end
これを解決するには、ヘッダではなく、実装ファイル(ClassA.m、ClassB.m)のほうで import する。しかし、それでは ヘッダ中のクラス名が解決できないため、ヘッダには @class ディレクティブでクラス名であることを宣言する。
[ClassA.h] @class ClassB; @interface ClassA { ClassB variableB; } @end [ClassA.m] #import "ClassB.h" ...
[ClassB.h] @import ClassA; @interface ClassB { ClassA variableA; } @end [ClassB.m] #import "ClassA.h" ...
さて、ここからが本題。
そもそも、ヘッダファイル中にヘッダの import を書くから循環参照が起きてしまう。ならば、最初からヘッダファイルではなく、実装ファイルの方で import すればよいのではないか。それで、必要に応じてヘッダファイル中で、@class や @protocol ディレクティブで宣言すれば良さそう。
ただし、基盤フレームワーク、UIKit/UIKit.h みたいなのは ヘッダファイルで import してもよいかもね。循環参照の恐れは無いし、いちいち @class で宣言するのはめんどくさい。
ということで、まとめ。