タイトルの通り、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; } @endClassAと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を使い前方宣言で対処できるのであればそれで解決できます。
@class ClassB; @interface ClassA: NSObject { ClassB *b; } @end
ClassB
@class ClassA; @interface ClassB: NSObject { ClassA *a; } @end
ただし、対象のクラスを継承していたり、処理内で対象のクラスをallocしたりしてる場合は#importを使わなければいけません。
以上でェェエェす。
0 件のコメント:
コメントを投稿