Change before you have to.

androidアプリ開発、iosアプリ開発、rails、deep learning .etc.を使った社会実験。

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

としてクラス宣言してやることで循環参照によるエラーを回避できます。