Recently someone on Stack Overflow told me that the code below does not leak, that the property handles retention itself:
self.locationManager = [[CLLocationManager alloc] init];
in dealloc :
self.locationManager = nil;
where in the .h file:
@property (nonatomic, retain) CLLocationManager *locationManager;
I thought that was an obvious leak and believed this should fix the leak:
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
However he claimed that would not work, because in his words : "you don't autorelease properties of a class. The autogenerated accessor of a property defined to retain will handle retention automatically"
And he made me wonder if he is wrong or have I not understood memory management at all?
EDIT 1: Is the code
self.myName=[NSSting stringWithFormat:@"%@ is correct.", @"TechZen"];
any different than
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
memory management-wise?
The guy says the first one is correct and refuses the second one. Why would the second one be SO WRONG? As far as I can see both assign autoreleased instances to some properties, but somehow there's still a stubborn argument that second one is wrong. I cannot see it, any help would be so welcome.
@jnic: you are amazingly wrong. as far as I understand it, the previous value of the property is sent the release message, not the object you want to assign to the property. so, yes the proposed code leaks indeed and you have to send an autorelease message just like you thought, ahmet emrah
The following statement is retained twice, and as such must be released twice:
This is probably best written as follows:
Now, this variable has been retained just once, and you can release it in the dealloc function of your class.
Also, if you run the following line of code, a release is called:
Since locationManager is synthesized, when you set it to nil, it gets released first.
Furthermore, if you did the following, locationManager would first be released, then reset behind the scenes:
Finally, the following would crash with an exc_bad_access, because you are double releasing locationManager when you set it to foo:
Counting retains and releases helps in this case. It is most definitely a leak. Your
locationManager
object will be retained 2 times: once by thealloc/init
calls, and once by the property. Setting the property tonil
will only release thelocationManager
once.For the examples given in Edit 1, they are indeed the same. It sounds like the other developer has an aversion to immediately autoreleasing or doesn't quite understand what
autorelease
does.The semantics of the retain property option are:
Therefore, your CLLocationManager instance will have a retain-count of 2 after the setter. One from alloc and one from the retaining setter. You should send a release message right after the setter:
Alternatively, add it to the autorelease pool so that it will at least be free'd eventually. Like you wrote yourself:
Even better, don't use the retain property option. Leave it as assign (the default) and you are set to go since you are using a retained object anyway.
Simple rule of thumb: If a property is marked as "retain", always give it an autoreleased variable (if you are creating it) unless of course you also NEED to retain it elsewhere.
Add this line underneath... It obviously gives your the retain count for locationManager. This will tell you if you need to release it manually or not.
edit: