Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IOS allocated objects is not referenced later in this execution path retain count +1

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

(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)

like image 913
Jann Avatar asked Nov 08 '12 17:11

Jann


2 Answers

Problem

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

Why is this retaining when I'm setting the property?

@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];

Why does it act like this?

If it didn't, then autoreleased objects returned from methods wouldn't be retained correctly!

Alternative Solution

If you don't like adding autorelease, simply assign to the underlying instance variable instead.

locationManager = [[CLLocationManager alloc] init];

In all cases...

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];

like image 96
WDUK Avatar answered Nov 16 '22 03:11

WDUK


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.

like image 24
Tommy Avatar answered Nov 16 '22 02:11

Tommy