将对象设置为 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 中向其发送释放消息有啥区别的主要内容,如果未能解决你的问题,请参考以下文章
Objective-C 中的实例变量是不是默认设置为 nil?
iPhone - dealloc - Release vs. nil