【问题标题】:Release or set to nil retained members释放或设置为零保留成员
【发布时间】:2011-07-18 12:08:11
【问题描述】:

将我保留的成员变量设置为 nil 还是在清理时释放它们更好?将保留的 var 设置为 nil 似乎是一种更安全的释放对象的方法,而不会有对其进行双重释放调用的风险。

更新:让我详细说明一下,我指的是已设置为具有保留属性的成员变量,即:

@property (nonatomic, retain) SomeClass* mInstanceVar;

【问题讨论】:

  • 嗨乔伊,如果我已经回答了你的问题,别忘了将我的答案标记为正确答案! ;)

标签: objective-c release retain


【解决方案1】:

最好先释放实例变量,然后在 -dealloc 方法中将它们设置为 nil。我个人喜欢这样做:

[myVar release], myVar = nil;

如果您将实例变量设置为nil,则不会释放它们,并且会导致内存泄漏。在发布后将它们设置为nil 将确保您不会导致泄漏,并且如果由于某种原因您稍后尝试访问这些实例变量,您将不会获得垃圾内存。


如果你有这样设置的实例变量,

@property (retain) NSObject *myVar;

那么在释放期间调用self.myVar = nil; 不是一个好主意。如果您的实例变量上有已注册 KVO 通知的对象,则调用 self.myVar = nil 将发送这些通知,而其他对象将收到通知,这很糟糕,因为它们会期望您仍处于有效状态 - 您如果您处于释放过程中,则不会。

即使它们没有注册 KVO 通知,这样做仍然不是一个好主意,因为当对象的状态不一致时,您永远不应该调用可能依赖于对象状态的方法(某些变量可能/将不存在) ,你应该自己处理这个过程。 [myVar release], myVar = nil; 就足够了。

如果您想了解更多信息,请阅读 Dave DeLong 对this 问题的回答。


对于初始化,调用属性 setter 和 getter 也是不好的(原因与上面大致相同)。在-init 调用中,您可以这样设置上述变量:

myVar = nil; // If you want to set it up as nil.
OR
myVar = [[NSObject alloc] init]; // Or set it up as an actual object.

避免 self.myVar = nilself.myVar = [[NSObject alloc] init 在您的类处于不确定状态的情况下(这些调用在 -viewDidLoad-awakeFromNib 中很好,因为到那时,您的类已经完全初始化,并且您可以依赖实例变量处于完整状态)。

【讨论】:

  • 我要么还是一头雾水,要么我的问题表述有误。我的意思是说我的实例变量上是否设置了保留属性。我会更新问题以反映这一点。如果您在这里的回答与此案有关,您能详细说明一下吗?我的理解是,具有保留属性的 var 在使用 '=' 设置时会保留一个对象,然后当我这样做时 = nil;它会释放那个对象。 就是我在这里问的情况。
  • 我已经更新了我的解释。如果还不清楚,请告诉我,我会补充。
  • 我想我明白你的解释了。那么,对于视图控制器,是否适合在 viewDidLoad 方法中使用保留属性“= nil”设置已清理的变量,而是在 dealloc 中使用 [var release]? (这就是我在他们的示例中观察到的,例如 ToolbarSearch 示例。)
  • -viewDidLoad 方法中,可以使用属性setter 和getter,因为那时你的类已经完全初始化了。但是,在-init 调用期间这样做不是一个好主意,原因与dealloc 调用相同。我已经更新了我的答案。
  • 如果你真的很懒,可以使用 Three20 宏来执行 release/nil 步骤...如果你不使用 Three20,那么只需编写自己的宏即可。#定义 TT_RELEASE_SAFELY(__POINTER) { [__POINTER release]; __POINTER = nil; }
【解决方案2】:

如果您仅通过属性访问器访问值,只需将属性设置为 nil 即可释放。

确保在dealloc 期间也将所有属性设置为nil

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    • 2012-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多