IOS分配的对象稍后在此执行路径中不会引用保留计数+1

Jan*_*ann 7 sdk memory-leaks instance-variables self ios

在我的appDelegate.h文件中,我这样做:

CLLocationManager       *locationManager;
Run Code Online (Sandbox Code Playgroud)

@property (nonatomic, retain) CLLocationManager *locationManager;
Run Code Online (Sandbox Code Playgroud)

然后在.m文件中:

...

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

...
Run Code Online (Sandbox Code Playgroud)

然而,我在XCode 4.5中得到以下内容(见附图)

泄漏的对象:此代码执行路径中未引用已分配的对象

(对象泄露:此代码执行路径中未引用已分配的对象)

有没有搞错?我在那条线后面引用它.

我没有看到这个问题.PS:没有崩溃,或任何事情.让我说清楚.这按原样运作的.我只是讨厌这个错误.我很确定我错过了一些愚蠢的东西.有人可以帮忙吗?

请不要发布任何关于"你不必再做@property"的内容等等.这段代码是为xcode 3.5-4~ish而写的,我更喜欢具体,因为我不想在两者之间来回翻转XCode 4.5允许的简写和旧项目需要的简写(并且仍然有源代码).所以我仍然使用.h文件中的完整定义.我认为编程风格的主要变化将伴随着应用程序的下一次重大更新.(感谢您的理解)

WDU*_*DUK 12

问题

如果这是非ARC(我认为是),那么请考虑一下这是如何工作的:

self.locationManager = [[CLLocationManager alloc] init];
    ^                                        ^
    Retains on setting                       |
                                             Retains when allocating
Run Code Online (Sandbox Code Playgroud)

为什么我在设置房产时会保留这个?

@property (nonatomic, retain) CLLocationManager *locationManager;
                         ^
                    This is why
Run Code Online (Sandbox Code Playgroud)

合成属性时,您将生成一个getter和setter(在大多数情况下).在nonatomicretain关键字提供线索的合成; nonatomic包装设置并进入内部@synchronized(self)以确保一次只有一个线程正在对其进行操作,并且retain告诉setter保留您放入它的任何值.重要的是要注意(对于旧版本的Xcode,而不是4.5),如果你不合成,那么这些将不会生效


在你的情况下,你保留两次.因此,如果在任何地方都没有释放,那么内存将被泄露.它很容易修复,只需使用:

self.locationManager = [[[CLLocationManager alloc] init] autorelease];
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

如果没有,那么从方法返回的自动释放对象将无法正确保留!

替代方案

如果您不喜欢添加自动释放,请简单地分配给基础实例变量.

locationManager = [[CLLocationManager alloc] init];
Run Code Online (Sandbox Code Playgroud)

在所有情况下...

确保在最合适的时间释放您拥有的内容,这些内容不会自动释放.对于保留的属性,self.locationManager = nil就足够了.对于替代解决方案,您需要执行[locationManager release];