どうも、俺@昼休みです。
タイトルの通り、Xcodeでコンパイルすると
「Cannot find interface declaration for 'XXXXClass', superclass of 'ZZZZClass'...」のエラーが出て困っていた俺へのめも。
何が起こってるかというと、簡単に言うと循環参照。
Objective-Cのクラスの前方宣言がないと困ること - アールケー開発に同じような内容の詳しい解説があります。
ClassA
#import "ClassB.h"
@interface ClassA: NSObject
{
ClassB *b;
}
@end
ClassB
#import "ClassA.h"
@interface ClassB: NSObject
{
ClassA *a;
}
@end
ClassAとClassBがそれぞれのヘッダファイルでお互いをimportしていて、
かつどちらかでどちらかのインスタンス変数を持っている、
またはどちらかのクラスを継承している、
ような場合にタイトルのような問題が発生します。
※コンソールからgccとかで直接コンパイルした場合は、
In file included from ClassA.h:2,
from ClassA.m:1:
ClassB.h:6: error: expected specifier-qualifier-list before ‘ClassA'
のようなエラーが出ます。困ったもんだ。
問題の詳細はコンパイルの処理にあり、
■ClassA.hのコンパイル
ClassA.h内で#import "ClassB.h"が見つかった時点でClassB.hをインポート(解析)する。
ClassB.h内にある#import "ClassA.h"が見つかりClassA.hをインポート(解析)するはずだが、#import宣言はネストしながらインポートしないため、実際はClassA.hのインポートは行われない。
ClassB.h内のClassAインスタンス変数の定義(ClassA *a;)で、ClassAの宣言が見つからないのでエラーとなる。
、、、そうです。
こういうような場合、#import宣言をやめて@classを使い前方宣言で対処できるのであればそれで解決できます。
ClassA
@class ClassB;
@interface ClassA: NSObject
{
ClassB *b;
}
@end
ClassB
@class ClassA;
@interface ClassB: NSObject
{
ClassA *a;
}
@end
ただし、対象のクラスを継承していたり、処理内で対象のクラスをallocしたりしてる場合は#importを使わなければいけません。
以上でェェエェす。