3

Possible Duplicate:
check retain count

As i was playing with retain, release counts, i ran into a situation, i am not able to explain. Please help me understand it better:

  • There is a class O. It contains no variables and does nothing.
  • There is a class Count. It initializes O and increments, decrements counts for it
  • There is a UI nib with 2 buttons: Retain and Release

enter image description here

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    o = [[O alloc]init]; // At this moment [o retainCount] is 1 as expected
    ....

For every doRetain, counts increments as expected

- (IBAction)doRetain:(id)sender {
    [o retain];

    NSString *result = [[NSString alloc] initWithFormat:@"%d", [o retainCount]];    
    [label setText: result];  
    [result release];

}

Whenever release is called, count is decreased

- (IBAction)doRelease:(id)sender {
    [o release];

    NSString *result = [[NSString alloc] initWithFormat:@"%d", [o retainCount]];
    [label setText: result];
   [result release];

}

Consider 1 retains and 2 releases

enter image description here

  1. We start off with a retain count of 1, after alloc init sequence
  2. Followed by manual retain count goes up to 2
  3. We then decrease the count and it goes down to 1
  4. After which next decrease ..... seemingly does nothing Retain count is still 1
  5. This release refers to bad memory and crashes the app.

Please help me understand this behavior

Community
  • 1
  • 1
James Raitsev
  • 92,517
  • 154
  • 335
  • 470

3 Answers3

4

If your retain count is 1 and you release, the object is no longer valid, and the releaseCount property is meaningless (and the results of which are unpredictable).

Also, I know this is a test, but you create your strings with 'alloc', but never release them.

When working with release and retain, you are only responsible for releasing YOUR OWN retains. Other objects may perform retains on the object in question, and they will, in turn, release them.

If you get an object using a method containing the words alloc, copy or create, there is an implied retain on said object. Otherwise, you can assume that the object will go away after the current run loop, so if you want to hang onto a copy of the object, you'll need to perform a retain. When you're done with the object, do a release.

Doug Kress
  • 3,537
  • 1
  • 13
  • 19
2

Actually, the retain count is a horribly misleading bit of data and is a horrible learning tool. The only time you can count on a retain count being a value you expect is if:

  • you subclass NSObject (or create your own root class)

  • do not pass your object to any system APIs at all

  • do not use autorelease ever

Once you violate any of those rules, the retain count becomes an implementation detail whose value is beyond your control. Certainly, in simple cases it will be relatively consistent. Until it isn't and then you are left debugging something based on false assumptions using tools that are inaccurate.

I.e.

do not call retainCount!

The cocoa memory management guide defines exactly how retains and releases should be managed.

You should treat the retain count as a delta; an operation will leave it unchanged or it will increase or decreases it. If you cause it to be increased, you must decrease to relinquish ownership. The absolute value matters not.

bbum
  • 162,346
  • 23
  • 271
  • 359
1

As mentioned on another recent post you should never really use the [retainCount] function!

check retain count

Community
  • 1
  • 1
Lee Armstrong
  • 11,420
  • 15
  • 74
  • 122
  • Well, then ... how do you keep track of your retain counts? – James Raitsev Aug 20 '11 at 17:13
  • 1
    You don't. You manage memory correctly in the first place. – jtbandes Aug 20 '11 at 17:13
  • 1
    I agree that you should never use them for your application, but they are useful in getting to understand how things work. And, @mac - you NEVER use retain counts to determine whether or not to release an instance. I'll elaborate on my answer. – Doug Kress Aug 20 '11 at 17:14