1

ARCは非常に推奨されているため、現在は実用的ではないかもしれない質問がありますが、メモリ管理を勉強していて、よくわからないことがあります。

私はこの方法を持っています

+(NSNumber *)releaseTooEarly
{
    NSNumber *createdNumber = [[NSNumber alloc] initWithInteger:5];

    NSLog(@"retain count before release: %d", createdNumber.retainCount); //Prints 2

    [createdNumber release];

    NSLog(@"%@", createdNumber); //Prints 5

    return createdNumber;
}
  1. オブジェクトが作成されたばかりの場合、保持カウントは 2 ではなく 1 にする必要がありますか?
  2. この種の状況では、値を返すことができるように autorelease を使用する必要があることを理解しています。呼び出し元は、割り当てが解除される前にそれを利用できます。代わりに保持を使用すると、すぐにオブジェクトの割り当てが解除されると思いましたが、次の NSLog はそれがまだ終了していることを示し、値が正常に返されます。

関数内でオブジェクトの割り当てを解除できない自動解放プール内にいるかどうか疑問に思っています。

ARC を使用する必要があることはわかっていますが、この結果の理由を理解したいだけです。

4

1 に答える 1

2

保持カウントの特定の値に依存しないでください ( http://whentouseretaincount.comを参照)。

この特定のケースでは ( http://www.opensource.apple.com/source/CF/CF-476.19/CFNumber.cで確認できるように)、(-1) から 12 までの整数値の作成済みオブジェクトをNSNumber キャッシュします。そのように

[[NSNumber alloc] initWithInteger:5];

繰り返しは常に同じインスタンスを返します。キャッシュには、オブジェクトへの追加の参照が 1 つ保持されます。これが理由でありretainCount == 2、オブジェクトを解放してもオブジェクトが実際に破棄されない理由も説明しています。

しかし、これは実装の詳細にすぎません!! . 上で述べたように、保持カウントは使用しないでください。また、オブジェクトの割り当てが解除されたとしても、必ずしもオブジェクトのメモリが無効になるわけではないため、オブジェクトにアクセスすると結果表示される場合があります。

ルールについては、『Advanced Memory Management Programming Guide』の「Basic Memory Management Rules」を参照してください。

  • 最終的にはrelease、または自分が所有autoreleaseするオブジェクトが必要です。
  • 名前が「alloc」、「new」、「copy」、または「mutableCopy」で始まるメソッドを使用して作成したオブジェクトを所有している</li>
  • を使用して所有権を取得すると、オブジェクトを所有しretainます。

メソッドの正しいバージョンは次のようになります

+ (NSNumber *)releaseCorrectly
{
    NSNumber *createdNumber = [[[NSNumber alloc] initWithInteger:5] autorelease];
    return createdNumber;
}

autoreleaseバランスを取りallocますが、呼び出し元のメソッドに戻ったときにオブジェクトがまだ有効であることを保証します。プログラム制御がメイン イベント ループに戻ったときなど、現在の自動解放プールが破棄されたときに解放されます。

于 2013-06-19T11:45:07.737 に答える