objective-cのweak, strongについて挙動の検証

京都のしがないスタートアップで働くCTOです。

技術ブログ始めてみました。

よろしくお願いしますー。

 

さてさて、社内勉強会用にobjective-cのproperty属性についてスライドを作りました。

 

 
社内で説明した時に
・ 強い参照(strong)
・ 弱い参照(weak)
についてツッコミが入りました。
この記事ではもう少し掘り下げて書いてみたいと思います。
 
○ オーナーシップ
ARC環境において、オブジェクトが解放されるかどうかは別のオブジェクトがそのオブジェクトの所有権を持つかどうかで決まります。所有権をもつオブジェクトがいる場合は、そのオブジェクトは解放されません。所有権を持つオブジェクトがいなくなると解放されます。この所有権の事を「オーナーシップ」といいます。
 
○ 強い参照
ARC環境において、あるオブジェクトへの参照がある限りそのオブジェクトが解放されないような参照の仕方を強い参照といいます。オブジェクトへの強い参照がなくなった場合、そのオブジェクトは解放されます。あるオブジェクトに対して強い参照を持つ事を「オーナーシップ」を持つといいます。
○ 弱い参照

強い参照とは反対に、あるオブジェクトへの参照を持っていたとしても、そのオブジェクトが解放されるような参照の仕方を弱い参照といいます。通常は強い参照があるオブジェクトに対して弱い参照で参照を行います。強い参照がなくなった段階でオブジェクトは解放され、弱い参照は nil で上書きされます。これを「ゼロ化」といいます。

 

と、書いてみてもなかなか伝わりづらい所かなと思います。
そのふるまいが分かる簡単なコードを書いてみました。
 
まず、検証用コード
 
 
strongStringは明示的に強い参照を指定しました。こちらに「テスト」文字列オブジェクトのポインタが代入されます。
明示的に指定しない場合もデフォルトで強い参照となります。
weakStrongには弱い参照を明示的に指定して「テスト」文字列オブジェクトのポインタを代入しました。
出力するといずれも「テスト」と出力されます。
 

f:id:jazzsasori:20140210230834p:plain

 
 
次にstrongStringに「あいう」文字列オブジェクトのポインタを代入しました。
「テスト」は唯一の強い参照であるstrongStringからの参照を失い解放されます。
weakStringはゼロ化によってnilで上書きされるため、出力はnilとなります。
 

f:id:jazzsasori:20140210230853p:plain

 
弱い参照を明示的に宣言して代入を行った場合、代入した瞬間に誰もオーナーシップを持たないため
その場で解放され、weakString2の出力はnilとなります。
※ これはxcodeが警告を出してくれます。
 

f:id:jazzsasori:20140210231046p:plain

 

 

弱い参照はIBOutletやdelegateに対して指定するとよいと思います。
delegateに強い参照を指定した場合、お互いにオーナーシップを持つため循環参照となってしまいます。注意して下さい。
 
ではでは