In my appDelegate.h file I do this:
CLLocationManager *locationManager;
and
@property (nonatomic, retain) CLLocationManager *locationManager;
Then later in the .m file:
...
@synthesize locationManager;
...
if ([CLLocationManager locationServicesEnabled])
{
[myGizmoClass setLocationManagerDisabled:FALSE];
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
[self.locationManager startUpdatingLocation];
...
Yet I am getting the following in XCode 4.5 (see image attached)
(Object leaked: allocated object is not referenced later in this code execution path)
What the heck? I reference it right after that line.
I am not seeing the issue. PS: No crash, or anything. Let me be clear. This is working as it is. I just hate the error. I am QUITE sure that I am missing something silly. Can anyone help?
Please do not post anything with regards to "You don't have to do @property anymore", etc. This code was written back for xcode 3.5-4~ish and I prefer being specific because I hate having to flip back and forth between the shorthand that XCode 4.5 allows and what older projects require (and still have in their source code). So I still use the full definitions in the .h file. I figured that the major change to programming style would come with the next major update of the app. (thanks for understanding)
If this is non ARC (which I assume it is), then think about how this is working:
self.locationManager = [[CLLocationManager alloc] init];
^ ^
Retains on setting |
Retains when allocating
@property (nonatomic, retain) CLLocationManager *locationManager;
^
This is why
When you synthesize a property, you are generating a getter and setter (in most circumstances). The nonatomic
and retain
keywords are providing hints to the synthesize; nonatomic
wraps the setting and getting within @synchronized(self)
to make sure only one thread is acting on it at a time, and retain
is telling the setter to retain whatever value you're putting in to it. It's important to note (for older versions of Xcode anyway, not 4.5), that if you don't synthesize, then these won't take effect
In your case, you are retaining something twice. Hence if there's no release anywhere, then the memory will be leaked. It's simple to fix, simply use:
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
If it didn't, then autoreleased objects returned from methods wouldn't be retained correctly!
If you don't like adding autorelease, simply assign to the underlying instance variable instead.
locationManager = [[CLLocationManager alloc] init];
Make sure you release what you have at the most appropriate time, these will not automatically release. For retained properties, self.locationManager = nil
will suffice. For the alternative solution, you will need to perform [locationManager release];
The @property
is defined to retain
. Therefore the following line:
self.locationManager = ...
Which is semantically equivalent to:
[self setLocationManager:...]
retains whatever is on the right hand side. But what you've supplied on the right hand side is an owning reference. So:
[[CLLocationManager alloc] init] // gives an owning reference
self.locationManager = ... // retains your owning reference; you've now
// incremented the reference count twice
Your location manager will be leaked.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With