編集: Apple の推奨事項に準拠するように変更されました。この回答に続くコメントは、私の元の (そして非常に悪い) バージョンを参照しています。今後は、iOS Developer Library のPractical Memory Managementに適切な注意を払います。
質問 (1) : いいえ、余分なリリースは必要ありません。の後[[ASArray alloc] initWithArray:array]
、アレイの保持カウントは になり1
ます。ではdealloc
、 を呼び出すと[_array release]
が返されるため0
、解放する必要があります。
その間に が呼び出された場合、新しいオブジェクトを保持し、古いオブジェクトを解放することによって[setArray:]
、そのプロパティ宣言に従います。retain
他のオブジェクトまたはメソッドが配列を保持している場合、それを解放するのは彼らの責任です。配列のretainCountが1
開始時よりも大きい場合dealloc
、他のオブジェクトが少なくとも一時的にそれを保持しています。
質問 (2) :retainCount
実行時に確認できますが、NSObject プロトコル リファレンスが警告しているように、オブジェクトが複数の自動解放プールに入ってしまい、そのカウントが無意味に高くなりがちです。
おまけ[[NSArray alloc] initWithArray:array]
:入力の保持カウントを使用して追加することを考えているかもしれません1
。これは、不変ソースへの参照を保持して渡すことによって「コピー」が作成された場合にのみ発生します。この場合、他のオブジェクトもそのソースへの参照を保持しています。 [[NSString alloc] initWithString:]
そのソースが不変であるかどうかを検出し、これを行います。[[NSArray alloc] initWithArray:]
ではない。 [NSArray copy]
一方、それ自体を保持して返します。
もちろん、これらの最適化は実装固有のものであり、決して想定すべきではありません。ただし、次のように、いくつかのオブジェクトを構築し、自動解放を回避し、それらのアドレスとretainCountsに従うことは教育的です。
NSArray *array1 = [[NSArray alloc] initWithObjects:@"a", nil];
// Do not just assign array1 to [[NSArray alloc] init], or you'll get a singleton empty array with a high retain count.
// Make array1 mutable, and array2 should be copied differently.
NSLog(@"Constructed array1");
NSLog(@"array1 address = %p retainCount = %d", array1, [array1 retainCount]);
NSArray *array2 = [array1 copy];
// Use [[NSArray alloc] initWithArray:] and the results may be different.
NSLog(@"Constructed array2");
NSLog(@"array1 address = %p retainCount = %d", array1, [array1 retainCount]);
NSLog(@"array2 address = %p retainCount = %d", array2, [array2 retainCount]);
[array1 release];
NSLog(@"Released array1");
NSLog(@"array2 address = %p retainCount = %d", array2, [array2 retainCount]);
[array2 release];