0

以下のコードは問題なく動作します。確認のためにシステムで実行できます。

私の質問は、ご覧のとおり、dealloc メソッドは保持カウントがゼロに達した場合にのみ呼び出されるということです。つまり、RetainTracker オブジェクト用にメモリが解放されます。ただし、問題は、dealloc メソッドで保持カウントをログに記録すると、依然として保持カウントが 1 と表示されることです。これはなぜですか?

これが私のコードです:

#import <Foundation/Foundation.h>
@interface RetainTracker : NSObject

@end

@implementation RetainTracker

- (id)init {

    if (self = [super init]) {
        NSLog(@"init: Retain count of %lu",(unsigned long)[self retainCount]);
    }
    return self;
}

- (void)dealloc {

    NSLog(@"Dealloc called bye bye!==>%lu",(unsigned long)self.retainCount);
    [super dealloc];
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        RetainTracker *myRetainTracker = [RetainTracker new];

        [myRetainTracker retain]; // count-->2
        NSLog(@"The retain count is ==>%lu",(unsigned long)myRetainTracker.retainCount);

        [myRetainTracker release];// count -->1
        NSLog(@"The retain count is ==>%lu",(unsigned long)myRetainTracker.retainCount);

        [myRetainTracker retain];// count -->2
        NSLog(@"The retain count is ==>%lu",(unsigned long)myRetainTracker.retainCount);

        [myRetainTracker release];// count -->1
        NSLog(@"The retain count is ==>%lu",(unsigned long)myRetainTracker.retainCount);

        [myRetainTracker release];// count -->0
        NSLog(@"The retain count is ==>%lu",(unsigned long)myRetainTracker.retainCount);

    }
    return 0;
}

ログは次のとおりです。

init: Retain count of 1
The retain count is ==>2
The retain count is ==>1
The retain count is ==>2
The retain count is ==>1
Dealloc called bye bye!==>1
The retain count is ==>1
4

2 に答える 2

3

これは驚くべきことではありません。releaseコードはおそらく次のようになります (疑似コード)。

- (void)release {
   if (retainCount > 1) {
      retainCount -= 1
   } else {
      // no need to set the retainCount to 0 here,
      // the object now ends its existence
      [self dealloc]
   }
}

また、最後NSLogに、実際には存在しなくなったオブジェクトにアクセスしているため、クラッシュする可能性があります。

読み取った値retainCountは決して当てにしないでください。それは単なる実装の詳細です。所有権の譲渡retainと考える方がはるかに安全です。release

retainCountドキュメントから:

この方法は使用しないでください。

この方法は、メモリ管理の問題をデバッグする際には役に立ちません。(...) このメソッドから有用な情報を取得できる可能性はほとんどありません。

于 2016-05-21T10:52:32.610 に答える
-1

プロジェクトを ARC に切り替えます。真剣に。3 年前に保持 / 解放について知っていたことをすべて忘れてしまいました。それ以外の場合、解放中のオブジェクトの保持回数は意味がありません。それについて疑問に思うのは無意味です。

于 2016-05-21T10:31:38.743 に答える