Objective-Cで、array1がmutableCopyを使用してarray2にコピーされ、コードがmain()で実行されたとすると、配列に含まれるオブジェクトを解放する責任は誰にありますか?main()またはarray2ですか?
4 に答える
以前の回答は要点を逃したか、質問者がかなり不明確だったと思います。実際の問題は、どちらの配列についても話しているのではなく、配列の内容についてです。
配列に含まれるオブジェクトを解放する責任は誰にありますか? main() ですか、それとも array2 ですか?
array1
との両方array2
がオブジェクトの解放を担当します。
NSArrayのドキュメントから:
「配列はその内容への強力な参照を維持します。マネージ メモリ環境では、各オブジェクトは、その ID が配列に追加される前に保持メッセージを受け取り、配列から削除されるか、配列が割り当て解除されると解放メッセージを受け取ります。」
まず、各オブジェクトは NSArray によって保持されますarray1
。array2
経由で作成する-mutableCopy
と、同じオブジェクトを指す NSMutableArray が取得され、それぞれが再び保持されます。array1
この時点で解放すると、そのdealloc
メソッドが呼び出されたときに、含まれている各オブジェクトが解放されます。ただし、array2
はそれらを保持しているため、オブジェクトは破棄されません。保持カウントが 0 に達した場合のみです。これは、array2
が破棄され、他の誰もオブジェクトを保持していない場合 (または から削除された場合array2
) に発生します。
コレクション クラス (配列、セット、辞書など) はその内容の保持と解放を処理するため、心配する必要があるのはコレクション自体の保持または解放だけです。を使用したので、-mutableCopy
暗黙のうちに を保持していることを思い出してくださいarray2
。
Obj-C でのメモリ管理については、このガイドを参照します。彼には配列と辞書に関するセクションがあり、ここに抜粋があります:
配列、辞書などは、通常、追加されたオブジェクトを保持します。(サード パーティのコレクション タイプのオブジェクトを扱う場合は、常にドキュメントをチェックして、それらが保持されているかどうかを確認してください)。これは、これらのコレクションがオブジェクトの所有権を取得し、追加する前に保持する必要がないことを意味します。
投稿のコメントも参考になります
オブジェクトを配列に格納しても、所有権の責任は変わりません。次に例を示します。
int main(int argc, char *argv[])
{
// ...
NSObject *obj1 = [[NSObject alloc] init]; // owned
NSObject *obj2 = [[NSObject alloc] init]; // owned
NSObject *obj3 = [[[NSObject alloc] init] autorelease]; // not owned
NSMutableArray *array1 = [NSMutableArray arrayWithObjects: obj1, obj2, obj3, nil]; // not owned
NSMutableArray *array2 = [array1 mutableCopy]; // owned
// ...
[array2 release];
[obj2 release];
[obj1 release];
// ...
}
このコードはobj1
とを直接割り当てるobj2
ため、それらを所有して解放する必要がありますが、 を自動解放obj3
するため、解放する必要はありません。同様に、 の結果を所有しarrayWithObjects:
ていないので解放しませんが、 の結果を所有しているmutableCopy
ので解放しなければなりません。配列に格納されているオブジェクトは関係ありません。気にする必要があるのは所有権だけです。
どちらの配列もコンテンツへの強い参照を保持しているため、配列が存在する限りobj1
、obj2
、およびの割り当ては解除されませんが、これはコントラクトの詳細であり、オブジェクトまたは配列の所有権を管理する方法には影響しません。obj3
NSArray
これらはすべて、配列ではなく、 Cocoa のメモリ管理規約の詳細です。
可変配列が不変配列に関連付けられても意味がありません。main() は array1 の解放を担当します。
ただし、私の経験では、オブジェクトを解放してもアプリケーションがクラッシュするだけです。ObjC は、メモリの自動管理にかなり優れています。私の Cocoa アプリは、数時間実行した後でも、最初よりも多くのメモリを必要としていないようです。