首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >此执行路径后面不引用已分配的IOS对象,保留计数+1。

此执行路径后面不引用已分配的IOS对象,保留计数+1。
EN

Stack Overflow用户
提问于 2012-11-08 17:49:26
回答 4查看 3K关注 0票数 7

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

代码语言:javascript
复制
CLLocationManager       *locationManager;

代码语言:javascript
复制
@property (nonatomic, retain) CLLocationManager *locationManager;

然后在稍后的.m文件中:

代码语言:javascript
复制
...

@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文件中的完整定义。我认为编程风格的重大变化将伴随着应用程序的下一次重大更新。(谢谢谅解)

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-11-08 17:54:32

问题

如果这不是ARC (我假设是这样),那么考虑一下它是如何工作的:

代码语言:javascript
复制
self.locationManager = [[CLLocationManager alloc] init];
    ^                                        ^
    Retains on setting                       |
                                             Retains when allocating

为什么在我设置房产的时候这个东西会被保留?

代码语言:javascript
复制
@property (nonatomic, retain) CLLocationManager *locationManager;
                         ^
                    This is why

当您合成一个属性时,您正在生成一个getter和setter (在大多数情况下)。nonatomicretain关键字为合成提供了提示;nonatomic封装设置并进入@synchronized(self),以确保每次只有一个线程对其进行操作,而retain则告诉设置者保留您对其投入的任何值。需要注意(对于较旧版本的Xcode,而不是4.5),如果不进行合成,它们将不会生效

在你的例子中,你要保留两次。因此,如果任何地方都没有发布,那么内存就会泄漏。它很容易修复,只需使用:

代码语言:javascript
复制
self.locationManager = [[[CLLocationManager alloc] init] autorelease];

为什么它表现得像这样?

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

替代解

如果不喜欢添加自动释放,只需将其赋值给基础实例变量即可。

代码语言:javascript
复制
locationManager = [[CLLocationManager alloc] init];

在任何情况下..。

确保您在最合适的时间发布您所拥有的,这些不会自动发布。对于保留的属性,self.locationManager = nil就足够了。对于另一种解决方案,需要执行[locationManager release];

票数 12
EN

Stack Overflow用户

发布于 2012-11-08 17:54:10

@property被定义为retain。因此,以下一行:

代码语言:javascript
复制
self.locationManager = ...

在语义上相当于:

代码语言:javascript
复制
[self setLocationManager:...]

保留任何在右边的东西。但你在右手边提供的是一个拥有的参考。所以:

代码语言:javascript
复制
[[CLLocationManager alloc] init] // gives an owning reference

self.locationManager = ...       // retains your owning reference; you've now
                                 // incremented the reference count twice

你的位置经理会被泄露的。

票数 2
EN

Stack Overflow用户

发布于 2012-11-08 17:54:45

请检查此代码:

代码语言:javascript
复制
CLLocationManager *location = [[CLLocationManager alloc] init];

self.locationManager = location;

[location release];

或者你需要做的是:

代码语言:javascript
复制
self.locationManager = [[[CLLocationManager alloc] init] autorelease];

[[CLLocationManager alloc] init]使retainCount变为1。

self.locationManager使retainCount增加1。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13294784

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档