objective-cの循環参照について
前回は「ARCでメモリリークを起こさないために」というタイトルで記事を書きました。
今回は「循環参照」について書こうと思います。
循環参照とは二つのクラスの間でお互いをインポートしてしまうことです。
こんな感じです。
まずクラスAでクラスBを使用するためにインポートします
#import "ClassB.h" @interface ClassA { ClassB variableB; } @end
今度は同様にクラスBでクラスAを使用するためにインポートします。
#import "ClassA.h" @interface ClassB { ClassA variableA; } @end
すると何がおこるかと言うと
このプログラムを理解しようとするコンパイラは
まずクラスAを理解しようとして、その中にあるクラスBを読みにいきます。
しかしクラスBにもクラスAが呼ばれているので、クラスAを読みにいき、・・・
この繰り返しをしてしまうので、実際には循環参照をしている時点でエラーになります。
この解決策として
まず、こんな循環参照になるような設計をしない!ということが大前提ですが、
それをいってしまうと根も葉もないので
以下のようにしてエラーを回避します。
まずクラスAは
#import "ClassA.h" @class ClassA; @interface ClassB { ClassA variableA; } @end
として、同様にクラスBも以下のようにします。
#import "ClassB.h" @class ClassB; @interface ClassA { ClassB variableB; } @end
つまり、
@class ClassX
としてクラス宣言してやることで循環参照によるエラーを回避できます。