【问题标题】:iOS potential leak of an objects propertyiOS 对象属性的潜在泄漏
【发布时间】:2014-07-12 06:37:00
【问题描述】:

我现在要从 ARC 切换到 MRC,因为我有一个旧项目。但是我对 MRC 不熟悉,现在当我分析我的代码时,可能存在对象属性的泄漏。

这里是代码

@property (nonatomic, retain) NSString *string;
@property (nonatomic, retain) AnotherObject *anotherObject;
- (id)init{
    ...
    _string = [[NSSting alloc] init];
    ...
}

- (void)doThings{
    self.anotherObject.text = self.string; // text is also a retain property of anotherObject,and anotherObject is also a property
}

- (void)dealloc{
   [_string release];
   [_anotherObject release];
   ...
}

我尝试修复它,所以我将_string 设为自动释放对象

- (id)init{
    ...
    _string = [[[NSSting alloc] init]autorelease];
    ...
}

并且仍然在dealloc 方法中释放_string,它可以工作,当我再次分析我的代码时,潜在的泄漏消失了。

但我不知道为什么,谁能帮我解释一下?非常感谢。

【问题讨论】:

  • 在您的 init 方法中,通常的模式是 _string = [[NSString alloc] init] (我假设这只是一个示例,因为通常您不会像那样创建一个空字符串)。然后 [_string dealloc] 在您的 dealloc 方法中。就像你拥有它一样。 anotherObject 是否被释放,anotherObject 是否正确释放 dealloc 中的 text 属性?
  • 是的,text 属性也在dealloc@AaronGolden 中发布
  • 我忘了说anotherObject也是self的retain属性
  • 也许anotherObject 正在泄漏并带走字符串。如果你在anotherObject的dealloc方法中设置断点,你打到了吗?

标签: ios objective-c memory-leaks


【解决方案1】:

在您的初始化方法中,您正在分配您的字符串。所以这意味着你的变量是对象的所有者。但是当它的工作完成时,它仍然保留着对象。因此,在这种情况下,您会收到潜在的泄漏警告。

但是在你放了自动释放之后,所以它是在工作完成时释放对象。所以你的潜在泄漏已经消失了。

Autorelease 只是从对象中删除一个保留计数,它不会像在 c 中那样立即“释放”内存。当自动释放池结束时,所有计数为 0 的自动释放对象都将释放其内存。

【讨论】:

  • 如果您直接为 ivar 分配自动释放,则在下一次自动释放池弹出后,它的保留计数为零。对于您在 dealloc 中发布的 ivar,这不太可能是您想要的。如果您在运行循环的较晚轮次中调用 doThings,而不是 init 方法,则 _string 很可能在您将其分配给 anotherObject.text 时已被释放。
【解决方案2】:

正确的模式是您最初尝试的模式。在 init 中分配没有自动释放的 ivar,例如:

_string = [[NSString alloc] init];

并在dealloc 中发布,例如:

[_string release];

如果你使用属性的setter,你需要使用autorelease,因为属性(被retain声明)会保留你分配给它的对象。因此,如果您使用 self.string = ... 分配字符串属性,那么它应该如下所示:

self.string = [[[NSString alloc] init] autorelease];

在您的问题中,您说静态分析器发现了错误。如果您在 Xcode 的问题选项卡中查看静态分析器消息,您实际上可以展开分析问题,Xcode 将向您显示分析器用于查看潜在泄漏的代码路径。这确实有助于追踪此类问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    • 1970-01-01
    • 2015-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多