稍后在此执行路径retain count+;中不会引用IOS分配的对象;1.
在我的appDelegate.h文件中,我执行以下操作:稍后在此执行路径retain count+;中不会引用IOS分配的对象;1.,ios,sdk,memory-leaks,instance-variables,self,Ios,Sdk,Memory Leaks,Instance Variables,Self,在我的appDelegate.h文件中,我执行以下操作: CLLocationManager *locationManager; 及 然后在.m文件的后面部分: ... @synthesize locationManager; ... if ([CLLocationManager locationServicesEnabled]) { [myGizmoClass setLocationManagerDisabled:FALSE]; self.locationM
CLLocationManager *locationManager;
及
然后在.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];
...
然而,我在XCode 4.5中得到了以下信息(见附图)
(对象泄漏:分配的对象稍后不会在此代码执行路径中引用)
怎么回事?我就在那一行之后引用它
我没有看到这个问题。附言:没有撞车,或者别的什么。让我说清楚。此正在按原样工作。我只是讨厌这个错误。我很确定我错过了一些愚蠢的事情。有人能帮忙吗
请不要发表任何关于“你不必再做@property”等内容的文章。这段代码是为xcode 3.5-4~ish编写的,我更喜欢具体,因为我讨厌在xcode 4.5允许的速记和旧项目需要的速记之间来回切换(它们的源代码中仍然有)。所以我仍然使用.h文件中的完整定义。我认为编程风格的重大变化将伴随着应用程序的下一次重大更新而来。(感谢理解)将
@属性定义为保留。因此,以下行:
self.locationManager = ...
语义上等同于:
[self setLocationManager:...]
保留右侧的任何内容。但您在右侧提供的是一个拥有的引用。因此:
[[CLLocationManager alloc] init] // gives an owning reference
self.locationManager = ... // retains your owning reference; you've now
// incremented the reference count twice
您的位置管理器将被泄漏。问题
如果这是非圆弧(我假设是),那么考虑一下它是如何工作的:
self.locationManager = [[CLLocationManager alloc] init];
^ ^
Retains on setting |
Retains when allocating
为什么我在设置属性时会保留此选项?
当您合成一个属性时,您正在生成一个getter和setter(在大多数情况下)。非原子
和保留
关键字为合成提供提示nonatomic
包装设置并进入@synchronized(self)
以确保一次只有一个线程作用于该设置,而retain
告诉设置程序保留您输入的任何值需要注意的是(对于旧版本的Xcode,而不是4.5),如果不进行合成,那么这些将不会生效
在你的情况下,你保留了一些东西两次。因此,如果任何地方都没有释放,那么内存就会泄漏。它很容易修复,只需使用:
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
为什么会这样?
如果没有,那么从方法返回的自动释放对象将无法正确保留
替代解决方案
如果不喜欢添加autorelease,只需将其指定给基础实例变量即可
locationManager = [[CLLocationManager alloc] init];
在所有情况下。。。
确保你在最合适的时间释放你所拥有的,这些不会自动释放。对于保留的属性,self.locationManager=nil
就足够了。对于替代解决方案,您需要执行[locationManager发布]代码>检查此代码:
CLLocationManager *location = [[CLLocationManager alloc] init];
self.locationManager = location;
[location release];
或者你需要像这样做:
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
[[CLLocationManager alloc]init]
使重新计数
为1
self.locationManager
使retainCount
增加1。在@property中,我看到您已指示希望locationManager保留。因此,将某些内容分配给self.locationManager将使保留计数增加到1。但是,由于还调用了alloc,因此现在将retain计数增加到2(这将导致泄漏)
解决方案:从alloc语句中删除self:
locationManager=[[CLLocationManager alloc]init]
如果不使用ARC,解决方案是在创建位置管理器后立即autorelease
位置管理器。因此,是self.locationManager=[[CLLocationManager alloc]init]autorelease]密码>答案?或者我应该这样做:locationManager=[[CLLocationManager alloc]init]代码>当我创建它时(删除“self”)?@Jann会这样做,这是一个风格问题。作为一般规则,您不应该在init
或dealloc
中使用getter或setter(因为这是对只部分构建或部分销毁的类调用方法),否则这是您喜欢的。
CLLocationManager *location = [[CLLocationManager alloc] init];
self.locationManager = location;
[location release];
self.locationManager = [[[CLLocationManager alloc] init] autorelease];