引用计数或保留计数问题(内存管理)

时间:2016-05-21 06:54:09

标签: objective-c memory-management manual-retain-release

以下代码运行正常,您可以在系统中运行以进行确认。

我的问题是,正如您所看到的,只有当保留计数达到零时才调用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

2 个答案:

答案 0 :(得分: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读取的值。这只是一个实现细节。将retainrelease视为所有权转移更为安全。

来自retainCount文档:

  

请勿使用此方法。

  

此方法在调试内存管理问题时没有任何价值。 (...)你不太可能从这种方法中获得有用的信息。

答案 1 :(得分:-1)

将项目切换为ARC。认真。我忘记了三年前我所知道的关于保留/释放的一切。除此之外,被释放过程中对象的保留计数无意义。这是毫无意义对此感到疑惑。