【问题标题】:iOS Memory Management followup. dealloc vs nil?iOS 内存管理跟进。 dealloc vs nil?
【发布时间】:2011-06-12 00:21:27
【问题描述】:

关于这个帖子: iPhone - dealloc - Release vs. nil

1) [foo release];
2) self.bar = nil;

解释如下:

  1. 正在释放对象,通过实例变量bar访问它。实例变量将成为一个悬空指针。这是dealloc中的首选方法。

  2. 将 nil 分配给 self 上的属性栏,这实际上将释放该属性当前保留的任何内容。如果您有属性的自定义设置器,请执行此操作,它应该清理的不仅仅是支持属性的实例变量。

有人可以澄清#1 的解释吗?通过实例变量bar访问?

例如,我在我的对象头中设置了一个私有变量:

SomeObject *oPointer;

我没有在头文件中使用带有此指针的属性设置器,它在实例化对象时确实不会合成。

在我的代码中,在某些条件下,我稍后必须分配这个指针并将其分配给它的对象。

obj = [[SomeObject alloc] initWith....];

所以现在可以通过实例变量 obj 访问它。我有一个 UIButton,它被配置为 RESET 这个对象,它附加的方法将它释放。我通过以下方式做到这一点:

[obj release];
obj = nil;

在所有解释问题之后,为什么我还必须声明 obj = nil? [obj release] 调用似乎也杀死了指针。我在想 [obj release] 会释放它指向的内存,并将 obj 设置为 nil 一次,但它似乎也杀死了指针,因为我的应用程序在 [obj release] 之后尝试引用 obj 时崩溃;

这个问题有意义吗?简单的解释是 [obj release] 做了 ALL 清理,包括杀死指针,我需要注意这一点?

如果我为 SomeObject 指针设置了一个保留属性,释放后指针是否仍会保留?

提前致谢!

【问题讨论】:

    标签: iphone objective-c ios memory-management


    【解决方案1】:

    Nil 更可取,原因有两个:

    • nil 可以安全地调用方法,而已释放的引用则不然。

    如果是 retain 属性,self.thinger = nil; 也会调用 release。如果没有,就不会。

    • 无论您使用retain 还是assign 属性都是您想要保持DRY 的代码,这意味着您不需要切换任何东西,除了assign/retain 标记并完成。在您的 deallocs 中使用 release 必须与属性保持同步。

    如果您严格使用autorelease,您几乎不需要自己调用release,除非在retain 属性的自定义设置器中。

    Check out the seminal article on NARC. Autorelease 是你的朋友。

    【讨论】:

      【解决方案2】:

      调用 release 会减少 obj 的引用计数。如果引用计数变为 0,那么它将被释放。指针 obj 仍然指向同一个内存位置,但是访问它很可能会导致程序崩溃。将 obj 设置为 nil 并不是绝对必要的,但会强化 obj 不再有效的想法。它在调试时或稍后在程序中如果您想选择性地重新创建 obj 并使用“if (obj != nil)”检查它是否已经创建时很有用。

      如果你将retain设置为一个属性,那么当它被调用为“self.obj = someObj”时,Objective C会在someObj的引用计数上加一。你永远不应该对通过 alloc-init 创建的东西调用 retain,因为 alloc-init 已经将引用计数设置为 1。如果你保留了该对象,那么当它被释放时,引用计数只会回到 1,它会成为内存泄漏。

      【讨论】:

        【解决方案3】:

        [obj release]; 减少对象 obj 指向的保留计数,并可能导致其被释放。这不会改变继续指向内存中某个位置的obj 指针。

        obj = nil;obj 指针设置为 nil。这是推荐的,但不是必需的。如果您不这样做但继续使用obj 指针,那么您可能会不小心尝试访问用于保存您在上面释放的对象的内存位置。如果该对象已被解除分配,这将导致崩溃,或者至少是意外行为。通过将 obj 设置为 nil,您可以确保将来对 obj 的任何使用都会以正常的、明确定义的行为向 nil 发送消息。

        【讨论】:

          【解决方案4】:

          释放对象仍然指向同一个对象。我总是同时执行 viewDidLoad 和 applicationDidFinishLaunching

          【讨论】:

            猜你喜欢
            • 2010-11-30
            • 2011-07-26
            • 1970-01-01
            • 2023-04-07
            • 2011-06-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多