2011-04-21 12 views
0
NSMutableString *ms = [[NSMutableString alloc]init]; 
[ms appendFormat:@"element %ld",1]; 
[ms appendFormat:@"element %ld",2]; 
NSMutableString *ms2 = [ms mutableCopy]; 
NSLog(@"ms retain count:%lu",ms.retainCount); 
NSLog(@"ms2 retain count:%lu",ms2.retainCount); 
NSValue *sw = [NSValue valueWithNonretainedObject:ms2]; 
NSMutableArray *a = [NSMutableArray array]; 
[a addObject:ms]; 
[a addObject:sw]; 
NSLog(@"ms retaincount %lu",ms.retainCount); 
NSLog(@"ms2 retaincount %lu",ms2.retainCount); 

答えて

13

あなたの問題は、retainCountが役に立つと予想していることです。

そうではありません、あなたはretainCount

をEXISTSことを忘れべきであるが、ここでは何が起こるかです:

NSMutableString *ms = [[NSMutableString alloc]init]; 

あなたは可変文字列を作成しました。 あなたはそれを所有し、あなたが文字列にいくつかのデータを追加releasingそれ

[ms appendFormat:@"element %ld",1]; 
[ms appendFormat:@"element %ld",2]; 

を担当しています。所有権の変更はありません。

NSMutableString *ms2 = [ms mutableCopy]; 

文字列のコピーを作成します。 あなたはNSValueであなたの文字列のコピーへのポインタを格納

NSValue *sw = [NSValue valueWithNonretainedObject:ms2]; 

それをコピーを所有してreleasingを担当しています。 NSValueを所有していない(したがってreleaseは必要ありません)、NonretainedObject:バリアントを使用しているため、ms2オブジェクトの所有権は変更されません。

NSMutableArray *a = [NSMutableArray array]; 

可変配列を作成します。あなたはそれを所有していません。

[a addObject:ms]; 

オブジェクトを配列に追加します。 配列は今もあなたは配列にオブジェクトを追加するオブジェクト

[a addObject:sw]; 

を所有しています。 配列は、今、あなたが所有し、このコードの末尾にオブジェクト(あなたはまだそれを所有していない)

を所有している:

  • ms
  • ms2

この手段をあなたのコードが正しいようにするには、あなたも持っている必要があります:

[ms release]; 
[ms2 release]; 

編集:「自分」対象とするとき、あなたがいない

方法を知っていますか?あなたが単語「new」で始まるメソッドを介してオブジェクトを取得する場合は、単語「alloc」または...

  • で始まるメソッドを介してオブジェクトを取得した場合

    • か:それはかなり簡単です...
    • あなたが明示的に「retain」オブジェクト

    ちょうど覚えている場合は、単語「copy」または...

  • が含まれているメソッドを介してオブジェクトを取得する場合:新-のAlloc-保持-コピー( "NARC")。これらの4つの条件のいずれかを満たしていれば、ドキュメント/メソッド宣言では別のことを言いません。オブジェクトを所有していて、そのオブジェクトのreleaseまたはautoreleaseを呼び出してその所有権を放棄しなければなりません。

    これは、すべてMemory Management Programming Guideに明白に配置されています。

  • +0

    はここにあなたのデイブありがとうそれはいくつかの奇妙な出力 –

    +0

    を示した理由出力は今、私は、これはそれが出力で2011年4月21日10たことを意味しないものを理解して:35:31.765 retaincountpgm [399:903] *** __NSAutoreleaseNoPool ():NSConcreteValueクラスのオブジェクト0x100110580が、プールなしで自動リースされました。ただ漏れました。 2011-04-21 10:35:31.766 retaincountpgm [399:903] *** __NSAutoreleaseNoPool():NSCFArrayクラスのプールなしでオブジェクトが0x100110ce0になりましたインプレース - jそれが言うだけで –

    +0

    @toddlerを漏出しています。あなたはおそらく 'main'でこれを実行しており、' NSAutoreleasePool'を作成していません。 –

    1
    1. 新しい可変文字列MSは、あなたは(あなたは「ALLOC」、それはあなたがそれを所有している場合*)ので、それは
    2. 同じ(と「自動解放」されていない)1の保持カウントで始まる所有していることを作成されます
    3. ms2はNSValueのswでラップされますが、swはms2(valueWithNonRetainedObject)を保持しないため、ms2の保持カウントは増加しません
    4. msとswが可変配列aに追加されます。

    *)を参照してください、それが配列の要素ではないのでしかしMS2のカウントを保持していない(ただし、NSValue SWの) - 配列は常にザが1だけ増加され、MSとSWのカウントを保持するので、その要素を保持しますthe memory management rules

    関連する問題