将对象设置为 nil 与在 dealloc 中向其发送释放消息有啥区别

Posted

技术标签:

【中文标题】将对象设置为 nil 与在 dealloc 中向其发送释放消息有啥区别【英文标题】:What's the difference between setting an object to nil vs. sending it a release message in dealloc将对象设置为 nil 与在 dealloc 中向其发送释放消息有什么区别 【发布时间】:2010-11-18 07:44:24 【问题描述】:

我有对象:

MyClass *obj= [[MyClass alloc] init];

两者有什么区别:

[obj release]; // Only obj own this object.

和:

obj = nil;

当我设置 obj = nil 时,ios 会释放 obj 吗?

我有一个指针,有时我将它设置为指向一个对象,有时没有。所以,当我想释放一个指针时,我必须检查它是否为零?

【问题讨论】:

【参考方案1】:

这是过去十年的答案,

现在只具有历史意义。

今天,你必须使用 ARC。

干杯


非常简短的回答是不要只需将其设置为 nil。 您必须释放它。 将其设置为 nil 与释放它无关。你必须释放它。

但值得记住的是,如果它是一个属性,那么

self.obj = nil;

实际上会为您发布它。当然,你不能忘记“自我”。部分!!!!

确实,

self.obj = anyNewValue;

确实会为您释放旧内存,神奇地清理所有内容并使用新值设置它。因此,self.obj = nil 只是其中的一个特例,它释放并清理所有内容,然后将其保留为 nil。

所以如果有人读到这篇文章是新人并且完全被记忆迷惑了,

    在设置为 nil x=nil 之前,你必须释放它,[x release]

    如果你正在使用一个属性,“不要忘记自我。东西”

    如果你正在使用一个属性,你可以直接说 self.x=nil 或者 self.x=somethingNew 并且它会负责释放和所有其他复杂的烦人的东西。

    最终,您将不得不学习所有关于发布、自动发布、等等等等的复杂知识。但人生苦短,暂时忘记它吧:-/

希望它对某人有所帮助。

再次注意,这篇文章现在是完全错误的。使用 ARC。

仅限历史兴趣。

【讨论】:

关于属性被神奇地释放的说法并不完全正确。如果你声明一个带有“retain”属性的属性,你必须自己释放它,只有当你用“copy”属性声明它时,它才会以所描述的方式为你释放。见developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/… 我认为他的意思可能是“分配”,而不是“保留”。还有,self.obj = someNewValue 不会触发 KVO 监听器吗? 澄清一下,如果您正确使用属性,self.obj = newValue 确实会释放旧值。我想补充一点,self.obj = newValue 与 [self setObj:newValue] 相同,这就是发布的方式(setObj 方法包含 [oldValue release])。另外,如果您要释放对象,您不想触发 KVO 吗? 有趣的是,有了 Swift,这个答案现在是双倍、高音、古色古香的!多么美好的世界……【参考方案2】:

Is It Necessary to Set Pointers to nil in Objective-C After release?

Release, Dealloc, and the Self reference

Setting an object nil versus release+realloc

阅读以上内容。他们全面地回答了你的问题

【讨论】:

【参考方案3】:

iOS 不支持垃圾回收,这意味着执行obj = nil 会导致内存泄漏。 如果您想自动控制解除分配,您应该执行以下操作:obj = [[[NSObject alloc] init] autorelease](如果您这样做,您必须释放它)。 Autorelease 会导致对象在当前 NSRunloop 事件结束时自动释放。 NSRunloop 会为每个事件迭代自动排空它的 NSAutoReleasePool,这通常很有帮助。

【讨论】:

我有一个指针,有时我设置 i 指向一个对象,有时我不这样做。所以,当我想释放一个指针时,我必须检查它是否为零? 为什么必须在发布时检查 nil?在objective-c中向nil指针发送消息是完全有效的,它什么也不做。不过,您应该始终将指针初始化为 nil 或其他一些有效对象。 我不明白为什么在发布前检查 nil 是个好主意。将 release 发送到 nil 是完全有效的,“真正的”非初学者编码人员一直都在这样做。为什么要学会避免被接受的常见做法?【参考方案4】:

将对象设置为 nil 将导致内存泄漏(如果您通过分配、保留或复制获得所有权),因为我们没有指向该特定内存位置的指针。

所以如果你想释放一个对象,你必须先取出一个对象的所有所有权,然后通过调用 release 方法使其为零。

[obj release];
obj=nil;

【讨论】:

以上是关于将对象设置为 nil 与在 dealloc 中向其发送释放消息有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

weak属性需要在dealloc中置nil么?

为啥在释放对象后使用'nil'

Objective-C 中的实例变量是不是默认设置为 nil?

iPhone - dealloc - Release vs. nil

关于 dealloc/release:做 x = nil; 总是可以的吗? [x 发布]; - 或者它会导致问题吗?

Objective-C在ARC下,把strong指针设置为nil,请问这样不会不释放指针的内存空间?