2011-11-08 6 views
1

私の質問はStackOverflowですでに議論されていますが、私のニーズに答えることができませんでした。だから問題は:オブジェクトをコピーしている間のメモリ管理

NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil]; 
NSMutableArray *secondArray = [[NSMutableArray alloc] init]; 
secondArray = [firstArray mutableCopy]; 

ここでsecondArrayの保持カウントは何ですか? 2または1?私はそれを2回または1回だけ放つべきですか? copyまたはmutableCopyは、COPYING(このイベントのsecondArray)オブジェクトの保持カウントを増加させますか?

答えて

5

絶対的な保持回数には注意しないでください。あなたは(ARCを使用しない場合、つまり)あなたが対応するreleaseまたはautoreleaseを必要とするすべてのallocnew*copymutableCopyretainための手段という、「バランス」だだけという。

このルールを各行に適用すると、2行目にallocが含まれていますが、リリースはありません。実際には、インスタンスをインスタンスに割り当てることは、あまり興味がないので絶対に無駄です。

NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil]; 
NSMutableArray *secondArray = [firstArray mutableCopy]; 
// There is no third line. 

をしかしさんがあなたの元のコードを議論し、何が起こったのか見てみましょう:だから、単純に読んでください

のObjective-Cでは
NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil]; 
NSMutableArray *secondArray = [[NSMutableArray alloc] init]; 
// secondArray points to a new instance of type NSMutableArray 
secondArray = [firstArray mutableCopy]; 
// You have copied another array (created a new NSMutableArray 
// instance) and have overwritten the pointer to the old array. 
// This means that the instance allocated in line 2 is still there 
// (was not released) but you don't have a pointer to it any more. 
// The array from line 2 has been leaked. 

が、私たちはしばしば所有権の話:非常にいくつかの方法があることオブジェクトの「所有者」にします。これらは次のとおりである:

  • alloc
  • new*、あなたがこれらを呼び出す場合newFoo
  • copymutableCopy
  • retain

に、あなたは責任するオブジェクトを取得すると。つまり、対応する番号releaseおよび/またはautoreleaseをこれらのオブジェクトに呼び出す必要があることを意味します。あなたは何が起こっている[[obj retain] retain];、その後[[obj autorelease] release];

+0

私はあなたが所有し、ある段階で解放される必要がある2つのオブジェクトがあると付け加えたいと思います。そして、あなたは正しいのです - 「retainCount」は単なるものです - 所有呼と解放呼の解放のバランスについて心配してください。 – Abizern

+0

実際には、secondArrayはコード内で遠く離れて割り当てられ、使用されています。私は便宜のために2行目に書きました。だから、メモリリークを避けるために私があなたを得たのであれば、まずsecondArrayを解放しなければなりません。これは絶対に有効でしょうか? –

+0

@AndreyChernukha:終了したら、 'secondArray'が指すオブジェクトだけを解放します。 'release'は次のことを意味します:*この行から、私はもうオブジェクトを必要としません。 * 'autorelease'は次のことを意味します:*すぐに、私はもうそれを必要としません。しかし、私はこの方法を離れるまで少なくとも生きていなければなりません。*(それは100%正確ではありませんが、有用であるためには真実に十分近い) – DarkDust

1
NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil]; 
NSMutableArray *secondArray = [[NSMutableArray alloc] init]; 
secondArray = [firstArray mutableCopy]; 

を行う場合たとえば、あなたはいいですよあなたがメモリリークを作成したということです。 firstArrayのmutableCopyをこの行で上書きしたときに、secondArrayに割り当てられた参照が失われました。

secondArray = [firstArray mutableCopy]; 

あなたは2回secondArrayをリリースする場合は、あなたが上書きされていないことを確認するために何をする必要がある

secondArray = [firstArray mutableCopy]; 

によって割り当てられた可変配列をoverreleasingているので、プログラムがクラッシュします誤って参照を保持し、残高はリリースで保持されます。