Question

I am trying to floss daily, get my exercise, and make sure I maintain a balance between my retains and releases.

Here is what has me puzzled. I have a ivar:

NSMutabledata *_alignmentData 

and a synthesized property associated with it:

// .h file
@property (nonatomic, retain) NSMutableData *alignmentData;

// .m file
@synthesize alignmentData=_alignmentData;

I start to pull data from a server asynchronously:

self.connection = 
[[[NSURLConnection alloc] initWithRequest:theRequest delegate:self] autorelease];

And immediately after allocate a data buffer to be used subsequently in the asynchronous callbacks:

// This prints 0. Cool.
NSLog(@"BEFORE [_alignmentData retainCount] = %d", [_alignmentData retainCount]);

// Create a place to receive the data that will arrive asynchronously:
self.alignmentData = [NSMutableData data];

// This prints 2. Shouldn't this be 1 ?!?
NSLog(@" AFTER [_alignmentData retainCount] = %d", [_alignmentData retainCount]);

To complicate matters in the first asynchronous callback that fires after the above allocation of self.alignmentData, I inspect the retain count again:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

    // This prints 1. 
    NSLog(@"[_alignmentData retainCount] = %d", [_alignmentData retainCount]);
    [self.alignmentData setLength:0];

}

So, it appears that the retain count rises to 2 from 0 then drops to 1. Can someone explain to me how this is possible?

Note: I've been told not to use retain counts as a debugging aid but that is simply not practical in a non-garbage collected language such as Objective-C.

Was it helpful?

Solution

It IS practical not to use retain counts as a debugging aid. In fact, it's experienced Objective-C coders who will tell you not to pay attention to retain counts. The people who worry about them in general are coders new to Objective-C, and they wind up being confused like you are.

You should not worry much about retain counts. The fact that something has more retains than you expect does not necessarily have anything to do with your code and does not necessarily indicate a bug, and the only way to determine which is the case is to use a proper debugging tool like you were advised to do in the first place.

In this particular case, 2 is the correct retain count for that object at that point in time because it was created with a retain count of 1, then retained by your setter method.

OTHER TIPS

From the Memory Management Programming Guide:

Retain Count

Typically there should be no reason to explicitly ask an object what its retain count is (see retainCount). The result is often misleading, as you may be unaware of what framework objects have retained an object in which you are interested. In debugging memory management issues, you should be concerned only with ensuring that your code adheres to the ownership rules.

I've never come across a situation where it's been useful to query an object's retainCount. If you follow proper memory management rules, you'll be fine.

As for your actual question, autoreleases don't happen immediately. They happen whenever the current autorelease pool happens to be popped. Since you're not explicitly managing any autorelease pools, then you have no control over when that autorelease happens. However, since you seem to be following correct memory management rules, you have nothing to worry about.

Maybe because you're allocating the object with a count of +1 and autorelase, then it get set to a property, which calls a retain on it, so +2, and the original object is autoreleased, so it drops to +1.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top