释放或设置为零保留成员
将保留的成员变量设置为零或在清理时释放它们是否更好?将保留变量设置为 nil 似乎是一种更安全的释放对象的方法,而不会冒双重释放调用的风险。
更新:让我详细说明一下,我指的是已设置为具有保留属性的成员变量,即:
@property (nonatomic, retain) SomeClass* mInstanceVar;
Is it better to set my retained member vars to nil or to release them when I am cleaning up? Setting a retained var to nil seems a safer way to release an object without risking a double release call on it.
Update: Let me elaborate that I'm referring to member vars that have been set to have the retain property i.e.:
@property (nonatomic, retain) SomeClass* mInstanceVar;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
最佳做法是首先释放实例变量,然后在
-dealloc
方法中将它们设置为nil
。我个人喜欢这样做:如果将实例变量设置为 nil,则不会释放它们,并且会导致内存泄漏。不过,在释放后将它们设置为 nil 将确保不会导致泄漏,并且如果由于某种原因您稍后尝试访问这些实例变量,则不会获得垃圾内存。
如果您有这样设置的实例变量,
那么在释放期间调用 self.myVar = nil; 并不是一个好主意。如果您的实例变量上有已注册 KVO 通知的对象,则调用 self.myVar = nil 将发送这些通知,并且其他对象也会收到通知,这很糟糕,因为它们会期望您仍然处于有效状态 - 如果您处于释放过程中,则不是有效状态。
即使它们没有注册 KVO 通知,这样做仍然不是一个好主意,因为当对象状态不一致时(某些变量可能/将不存在),您永远不应该调用可能依赖于对象状态的方法,并且您应该自己简单地处理这个过程。
[myVar release], myVar = nil;
就足够了。如果您想了解更多信息,请阅读 Dave DeLong 对此的回答问题。
对于初始化,调用属性 setter 和 getter 也不好(出于与上面相同的原因)。在
-init
调用中,您可以这样设置上述变量:避免
self.myVar = nil
和self.myVar = [[NSObject alloc] init
如果你的类处于不确定状态(不过,这些调用在-viewDidLoad
和-awakeFromNib
中很好,因为到那时,你的类已经已完全初始化,并且您可以依赖实例变量处于完整状态)。It's best practice to release your instance variables first, and then set them to
nil
in your-dealloc
method. I personally like doing that like so:If you set your instance variables to
nil
, you're not releasing them, and you're causing a memory leak. Setting them tonil
after releasing though will ensure that you're not causing leaks, and if, for some reason, you try to access those instance variables later, you're not going to get garbage memory.If you have an instance variable set up as such,
then it is not a good idea to call
self.myVar = nil;
during deallocation. If you have objects that have registered for KVO notifications on your instance variable, callingself.myVar = nil
will send those notifications, and other objects will be notified, which is bad because they will be expecting you to still be in a valid state—you're not if you're in the deallocation process.Even if they're not registered for KVO notifications, it's still not a good idea to do that because you should never call methods that could rely on your object's state when its state is inconsistent (some variables might/will be nonexistent), and you should simply handle the process yourself.
[myVar release], myVar = nil;
will suffice.If you want more information, read Dave DeLong's answer to this question.
For initializing, it is also not good to call property setters and getters (for much the same reason as above). In an
-init
call, you would set up the aforementioned variable as such:Avoid
self.myVar = nil
andself.myVar = [[NSObject alloc] init
in cases where your class is in an undeterminate state (these calls are fine in-viewDidLoad
and-awakeFromNib
, though, because by that point, your class has been completely initialized, and you can rely on the instance variables to be in a complete state).如果您仅通过属性访问器访问值,只需将属性设置为 nil 即可释放。
确保在
dealloc
期间将所有属性设置为nil
。If you're only accessing the values by way of the property accessors, simply set the property to
nil
and it will release.Make sure to set all your properties to
nil
duringdealloc
as well.