Why call auto advertisements to define iVar in init method?
I'll just familiarize myself with the CLLocationManager and found some example 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 iVar will be auto-implemented. Does this mean that it is not freed at the end of the init method?
I am also puzzled to see that the same example codes have iVar release in the dealloc method.
Any thoughts?
a source to share
locationManager
is a property that is probably set with an attribute retain
.
Basically, if you only write:
self.locationManager = [[CLLocationManager alloc] init];
the left operator self.locationManager
retains a reference to the highlighted one CLLocationManager
. But the link to the right side CLLocationManager
itself is never released. The save count for this manager never reaches zero and the object never leaves - this causes a memory leak.
There are two ways to solve this problem. Either the autorelease
allocated object, as you saw in the above code snippet, or you assign the allocated object to a temporary variable, store the temporary variable in the property locationManager
, and then explicitly free 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 people prefer this second approach because they don't like waiting for the auto-resource pool to be "empty", especially on a low-memory device like the iPhone, and this provides tighter control over the object's lifespan.
Apple Objective-C The programming language describes this attribute in more detail.
a source to share
If your self.locationManager is a property storing it, it sets the persistence. By using alloc, you are setting the hold value to +1, which means it is +2 by the end of the function. When you say autorelease it will be +1 (because of the retention property). You can also explicitly free it after setting its property, but what you are doing is less code and easy to read.
a source to share
There is an alternative without a temporary variable or abstract:
locationManager = [[CLLocationManager alloc] init];
Without using, self.locationManager
you don't call the setter method on that variable, and as a result, you don't increase the hold count to 2. The compiler changes these assignments to [self setLocationManager: locationManager];
. This assumes you've prototyped the variable as a save.
If it is a class variable (it is), you can just do the job. It is debatable whether this is a good coding practice, but in my opinion it depends on where it is in the initiation class.
a source to share