2009年8月31日月曜日

iPhone:インスタンスの生成と破棄(その2)

iPhoneにはガベージコレクションのような機能は無く、アプリケーション開発者は自らメモリ解放の管理をする必要があります。これは、安定したアプリケーションを作るためには特に重要なテーマだと思いますので、再度自分の理解をまとめ直します。

参照カウンタの考え方と自動破棄については前回記事を参照してください。

今回は、インスタンスを生成するオブジェクト(オーナー)がするべき処理を5つパターンに分けて整理します。

インスタンスを生成する目的
(A)生成したインスタンスをイベント処理中だけ、一時的に使用したいケース
>イベント終了時には、生成したインスタンスが確実に破棄される必要があります
(B)生成したインスタンスを、インスタンス変数に格納して保持したいケース
>イベント終了後もインスタンスが破棄されないで存続する必要があります

生成するインスタンスが自動破棄の対象か否か
(1)自動破棄の対象である(alloc/new/copy以外の方法で生成する場合)
(2)自動破棄の対象ではない(alloc/new/copyで生成する場合)

上記の組み合わせの4通りに加えて、(A-1)の例外的なパターンとして以下を挙げます。
(A-1')一時的に使用するインスタンスをイベント中に大量に生成するケース

以下、それぞれのケースについてシーケンスを図示します。


(A-1)一時使用目的のインスタンス/自動破棄対象
このケースでは特に気をつける点は有りません。生成したインスタンスはイベント終了時に自動的に破棄されます。
(A-2)一時使用目的のインスタンス/自動破棄対象外
このケースでは、自動破棄はされませんので、使用後、オーナーオブジェクトから忘れずにreleaseを実行する必要があります
(B-1)保持目的のインスタンス/自動破棄対象
保持目的のため、自動破棄されると困ります。何もしないとイベント終了時に破棄されてしまいますので、生成時にretainをしておく必要があります
(ここ少し自信が有りません。確認予定)

(B-2)保持目的のインスタンス/自動破棄対象外
このケースでは特に気をつける点はありません。

(A-1')一時使用目的のインスタンスを大量に生成する場合
(A-1)の例外的なケースです。生成するインスタンスが大量で、イベント終了まで待っているとメモリが不足してしまうような場合にこのパターンを検討する必要があります。

オーナーオブジェクトは自前のNSAutoReleasePoolを作成します。その後インスタンスを生成すると自前のNSAutoReleasePoolの方に登録されます。オーナーは任意のタイミングでNSAutoReleasePoolします。するとそれに登録されていたすべてのインスタンスが破棄されます。

単に破棄したいインスタンスにreleaseを送ってはいけないのかと思いましたが、それだと最終的にNSAutoReleasePoolが2重開放してクラッシュするとのことです。

0 件のコメント:

コメントを投稿