Amit Thakur
Amit Thakur

Reputation: 1081

Reference Count or Retain Count Issue (Memory Management)

The below code works fine, you can run it at your system for confirmation.

My question is, as you can see, the dealloc method is only called when the retain count reaches zero, meaning the memory is freed for the RetainTracker object. However, the issue is when I log the retain count in dealloc method, it still shows a retain count of 1. Why is this?

Here is my code:

#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;
}

Here are the logs:

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

Upvotes: 0

Views: 89

Answers (2)

Sulthan
Sulthan

Reputation: 130082

This is not surprising, the release code probably looks like this (in pseudocode):

- (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]
   }
}

Also, your last NSLog is actually accessing an object that no longer exists which can result in a crash.

Note that the value read from retainCount should never be relied upon. It's just an implementation detail. It is much safer to think about retain and release as transfer of ownership.

From retainCount documentation:

Do not use this method.

and

This method is of no value in debugging memory management issues. (...) it is very unlikely that you can get useful information from this method.

Upvotes: 3

gnasher729
gnasher729

Reputation: 52530

Switch your project to ARC. Seriously. I have forgotten everything I knew about retain / release three years ago. Other than that, the retain count of an object in the process of being released is meaningless. It's pointless wondering about it.

Upvotes: -1

Related Questions