iPhoneOSじゃなくてiOSになりましたが。
追記20100609 公式版メモリ管理ポリシーの日本語版を落としていたのを思い出して読んでみたところ、メソッド(メッセージ)の種類によってはreleaseが必要な場合があるらしいので追記。公式ドキュメントはちゃんと読むべきですね
Objective-Cのretain/releaseルールをすっかり忘れていたので再勉強。
ひさしぶりなので手動の参照カウンタ管理が面倒だったんですが、
http://wwwa.dcns.ne.jp/~nito/CocoaClub/
のサイトに、"参照カウンタ"では無く、"保持カウンタ"と書いてあるのをみて
非常にしっくりきました。参照する場合にカウンタを++するのではなく、保持する
場合に、保持する側のオブジェクトが++するんですね。
このサイトにもretain/relaseルールが書いてありましたが、今までの自分の他言語での経験が邪魔をするし少し違和感もあるので自分用にルール決め:
<retain/releaseルール>
(原則)
1.保持する・しないは全てオブジェクト目線。
2.releaseはオブジェクトインスタンスを解放するものではない (解放することもある)
releaseは保持をやめる・参照しないことを宣言するだけ
3.関数内でalloc - initしたら、まずその近くにreleaseを書く。 (オブジェクトを参照するコードは後でinit~release間に挿入するように書く) 追記:20100609
new〜や〜Copyの場合の場合もreleaseが必要
4.ただし、そのオブジェクトを関数呼び出し元に返すなら、autoreleaseにする。
5.コンストラクタ(init)内で alloc-initしてメンバ変数に保持するコードを書いたら、すぐにデストラクタ(dealloc)にreleaseを書く
6.NSArray arrayWith~等で生成したオブジェクトを含め、別オブジェクトから受け取ったオブジェクトはreleaseしない (生成している・していないは意識しない。意識してしまいがちだけど、どちらにしろreleaseするのは呼び出し先のオブジェクトの役目) 追記:20100609 new〜や〜Copyで受け取った場合はreleaseが必要
7.別オブジェクトから受け取ったオブジェクトを継続的に参照する(保持する)ならretainする。
8.retainを書いたらすぐにreleaseもしくはautoreleaseを書く。 書く場所はalloc-init時と同じ
9.構造体にはオブジェクトを格納しない。(保持する側でretainすることができず、保持させる側がretainせざるをえないから)
クラスを作って@property (retain)で格納する。 retainしているので、 ルール8を適用する
(例外)
10.循環参照になる場合はretainしない
11.外部ライブリ等に上記ルールに沿ってなくて、保持する必要があるオブジェクトをretainしないものがあったらどうしよう? (考えすぎ?)
(補足)
Delphiユーザーなど、オブジェクトは基本的にCreate/Freeしなければならない言語を使っている場合、 Createを書いたらすぐにFreeを書く癖をつけている人も多いと思います。(関数内のみで使うなら try .Create finally .Free end まで一気に書いてしまうと思います)
そういう場合、ルール3,4を実践するのは簡単でしょう。
でも、そういう癖がついていればいるほど他人が書いたObjective-Cソースを見ると混乱すると思います。例えばアプリケーション開始時にコントロール(UIView)群を作成する場所で
UIXXXView *xxx = [[ UIXXXView alloc] init~]; // コントロール生成
[window addSubView:xxx]; // 親ウインドウにコントロール貼り付け
[xxx release]; // すぐリリース????
となっているソースを良く見かけます。 普段の感覚でreleaseをインスタンスの解放だと思ってしまうとすぐにreleaseしていることに違和感ありまくり。
親ウインドウにコントロールを貼り付けたのに、すぐに解放するなんて。後で使うやろ?
でもルール2により、releaseはインスタンスの解放では無いと考えると納得できます。
親ウインドウ側ではルール7によってコントロールをretainしていると考えることができるので、ここでreleaseしてもインスタンスは解放されません。
コントロールが不要になって親ウインドウがreleaseした時に初めてインスタンスが解放されます。
と、ここまで書いてやっと自分でもすっきり腑に落ちた気がします。
(ここから妄想)
最近のコメント