views:

208

answers:

3

Hi, I just familiarise myself with the CLLocationManager and found several sample class definitions that contain the following init method:

- (id) init {
    self = [super init];

    if (self != nil) {
        self.locationManager = [[[CLLocationManager alloc] init] autorelease];
        self.locationManager.delegate = self;
    }
    return self;
}

- (void)dealloc {
    [self.locationManager release];
    [super dealloc];
}

I don't understand why the iVar would be autoreleased. Does this not mean it is deallocated at the end of the init method?

I am also puzzled to see the same sample codes have the iVar release in the dealloc method.

Any thoughts? '

+5  A: 

The locationManager is a property that is likely set with the retain attribute.

Basically, if you only write:

self.locationManager = [[CLLocationManager alloc] init];

the left-side self.locationManager setter retains a reference to the allocated CLLocationManager. But the right-side CLLocationManager reference is itself never released. The retain count for this manager never hits zero and the object never goes away — this causes a memory leak.

There are two ways to address this. Either autorelease the allocated object as you've seen in the code snippet you cited — or you assign the allocated object to a temporary variable, retain the temporary variable to the locationManager property, and then explicitly release the temporary variable:

CLLocationManager *_temporaryReference = [[CLLocationManager alloc] init];
self.locationManager = _temporaryReference; // this is retained
[_temporaryReference release];

Both approaches are equivalent, in terms of memory management. Some prefer this second approach because they don't like waiting for the autorelease pool to be "emptied", especially on a low-memory device like an iPhone, and this provides tighter control over an object's lifespan.

Apple's Objective-C Programming Language documentation explains this attribute in more detail.

Alex Reynolds
Hi Alex, yet again you lift my confusion. Thanks a lot
iFloh
+1  A: 

If your self.locationManager is a property that retains it, then it sets the retain. By doing alloc you do set the retain count to +1, which means that by the end of the function it's +2. When you say autorelease, it'll be +1 (because of the retaining property). You could also explicitly release it after setting it to the property, but what you're doing is less code and easy to read.

niklassaers
This is misleading. Autorelease does not change the retain count. All it does is add the object to an autorelease pool which will send a release to the object when the pool gets drained. In any case it's best not to even think about retain counts. Think only in terms of ownership. The object was obtained with the alloc method, therefore you own the object. You must therefore release it or autorelease it to relinquish ownership when you are done with it.The property can safely be left to sort out its own ownership issues.
JeremyP
Thanks for the clarification from both of you. I thought it was very clear and am glad for Jeremy's retain count lesson since this is what it all comes down to ...
iFloh
Jeremy's comment is important. The "autorelease pool" probably should have been called the "autorelease list", since people often see the word "pool" and mistakenly assume that it's something like the heap or a memory zone that actually contains objects. Autorelease is just a delayed messaging facility.
NSResponder
+1  A: 

There is an alternative without the temporary variable or the autorelease:

locationManager = [[CLLocationManager alloc] init];

Without using the self.locationManager you are not calling the setter method of the class for that variable and as a result not increasing the retain count to 2. The compiler changes these assignments into [self setLocationManager: locationManager];. This assumes that you have prototyped the variable as retain.

If it is a class variable (which it is) you can just make the assignment. It is debatable whether this is good coding practice but in my opinion it depends on where it is in the class initiation.

Stoaty