循環参照とその回避
GodがCreatureを所持しているとしましょう。
God has Creatureの関係なので当然GodはCreatureを知っている(参照を持っている)が、
CreatureもGodを知っていなければいけないという状況はよくあります。
例としては、カードゲームクラスはカードを持っているけど、カード側で何か処理をするときにゲーム自体の情報も必要になるとか。
ソースの例
---God.h--- #import "Creature.h" @interface God { Creature* _creature; // 往々にしてcreatureの配列を持つのだろうが。 } @property(retain) creature; ---God.m--- @synthesize creature = _creature; ---Creature.h--- @class God; @interface Creature { God* _god; } // 普通は必要ない @property(assign) god; ---Creature.m--- #import "God.h" @implemention Creature //普通は必要ない @synthesize god = _god;
説明
GodでCreatureをインポートして、CreatureでGodをインポートすると循環参照でエラーになる。
これを回避するには、Creature.hではクラスディレクティブ@classを使って、Godを「知る」だけにする。Creature.mでGodインポートする。
CreatureはGodを知っているだけでよく、God内のデータを操作したり、ましてや新しく_godにGodオブジェクトを代入したりなどという
身の程をわきまえない行為は普通許されない。
また、外部からわざわざCreatureを通してGodを知るということは普通無いだろう。
したがってCreature側から@propertyでgodを持っている必要は無いし、あったとしても読み専用readonlyなので気にする必要がないが、
あえて@propertyでgodをreadwrite(※readwriteはデフォルト値なので省略可)で宣言するなら、assignにしておく。
なぜならお互いてretainし合ってしまうと循環保持になっていつになっても解放されないから。
あんまりちゃんと考えてないとこういうテキトーな記事になってしまうが、とりあえず。