【问题标题】:Do I need to release IBOutlets in dealloc?我需要在 dealloc 中释放 IBOutlets 吗?
【发布时间】:2011-06-13 02:58:20
【问题描述】:

我有一个视图控制器作为导航控制器堆栈的一部分,带有两个 IBOutlets。在 viewDidUnload 我释放它们:

- (void)viewDidUnload
{
    self.myView1 = nil;
    self.myView2 = nil;
    [super viewDidUnload];
}

但我仍然有泄漏。所以我也为他们在 dealloc 中加入了发布消息:

- (void)dealloc
{
    [myView1 release];
    [myView2 release];

    [super dealloc];
}

这似乎可以清除内存泄漏。然而,我总是被告知我应该发布我使用 alloc、copy 或 new 创建的 ivars。所以我担心这两个版本在这里。这是对还是错?有人可以向我解释一下吗,因为我不断收到相互矛盾的意见...谢谢!

【问题讨论】:

    标签: ios objective-c memory-leaks uiviewcontroller


    【解决方案1】:

    基本的、安全的模式是

    • 声明 ivar
    • 为 ivar 声明 IBOutlet 属性
    • 在 dealloc 中释放属性
    • 仅引用属性,绝不是 ivar

    xib 设置属性,它首先释放可能存在的任何内容。

    我有点困惑为什么会有泄漏。将属性设置为 nil 应该释放旧的引用。也许 viewDidUnload 甚至没有被调用?你确定你甚至需要 viewDidUnload 吗?

    【讨论】:

    • 是的,viewDidUnload 从未被调用过。我一直在 Stack 上环顾四周,很多人也这么说……我猜操作系统会缓存它以防再次需要它?我认为 viewDidUnload 确实在出现内存警告时被调用,但它不是给定的。
    【解决方案2】:

    通过使用 IBOutlet,变量暴露在 Interface Builder 中,并在初始化视图控制器时分配。所以它们必须被释放和释放,因为视图控制器被卸载和释放。由于大多数 IBOutlets 都是保留的 UI* 属性,因此这是必要的。

    从技术上讲,将 nil 分配给变量并不是解除分配。它只是保留计数为 0 的最后一个状态,就在实际被释放之前。

    另外,请注意它们是使用 self.这意味着,来自视图控制器的引用变为 nil,而不是分配。

    总之,IBOutlet 属性必须在 dealloc() 中释放

    (虽然我很有信心,但其他人可能会为此提供100%正确的答案。)

    【讨论】:

    • 如果您使用点格式的访问器将您的属性设置为 nil,并且您的属性是(保留)类型,那么您将释放之前存在的任何对象。属性设置器看起来像这样(伪代码)[myProperty release];我的属性 = 新对象; [newObject 保留];
    【解决方案3】:

    如果您的任何@property 对象被声明为retaincopy,您需要在dealloc 中释放它们。这包括您的网点。

    【讨论】:

    • 谢谢。我听说过“分配、复制或保留”的规则,但并没有真正考虑到 XIB 在加载时保留它的事实。我会试着把它铭刻在我的脑海里!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 2012-01-22
    相关资源
    最近更新 更多