iOS内存管理跟进。 dealloc vs nil?

时间:2011-01-19 19:48:41

标签: iphone objective-c ios memory-management

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

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

解释如下:

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

  2. 将nil分配给self上的属性栏,实际上会释放当前保留的属性。如果你有一个属性的自定义setter,那么这样做是为了清除不只是支持属性的实例变量。

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

    访问

    例如,我在对象标题中设置了一个私有var,如下所示:

    SomeObject *oPointer;
    

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

    在我的代码中,在某些条件下,我后来必须分配并将此指针指定给它的对象。

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

    现在可以通过实例变量 obj 访问它。我有一个UIButton配置为重置此对象它的附加方法deallocs它。我这样做是通过:

    [obj release];
    obj = nil;
    

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

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

    如果我为SomeObject指针设置了retain属性,指针在释放后仍会保留吗?

    提前致谢!

4 个答案:

答案 0 :(得分:4)

Nil是优选的,原因有两个:

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

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

  • 您是否使用retainassign属性是您要保留DRY的代码,这意味着您不需要切换assign/retain标记以外的任何内容并完成。在deallocs中使用release必须与属性保持同步。

如果严格使用autorelease,除了release属性的自定义设置器外,您几乎不需要自己致电retain

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

答案 1 :(得分:3)

调用release会减少obj的引用计数。如果引用计数变为0,则将其取消分配。指针obj仍然指向相同的内存位置,但访问它可能会导致程序崩溃。将obj设置为nil并非绝对必要,但强化了obj不再有效的观点。它可以在调试时使用,或者稍后在程序中,如果你想要重新创建obj并使用“if(obj!= nil)”检查它是否已经创建它。

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

答案 2 :(得分:3)

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

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

答案 3 :(得分:0)

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