ios 使用 ARC 时,我是否在 dealloc 中将属性设置为 nil?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7906804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Do I set properties to nil in dealloc when using ARC?
提问by emfurry
I am trying to learn Automatic Reference Counting in iOS 5. Now the first part of this question should be easy:
我正在尝试在 iOS 5 中学习自动引用计数。现在这个问题的第一部分应该很简单:
Is it correct that I do NOTneed to write explicit release-property statements in my dealloc when using ARC? In other words, is it true that the following does NOTneed a explicit dealloc?
@interface MyClass : NSObject @property (strong, nonatomic) NSObject* myProperty; @end @implementation MyClass @synthesize myProperty; @end
My next and more important question comes from a line in the Transitioning to ARC Release Notesdocument:
You do not have to (indeed cannot) release instance variables, but you may need to invoke [self setDelegate:nil] on system classes and other code that isn't compiled using ARC.
This begs the question: how do I know which system classes are not compiled with ARC? When should I be creating my own dealloc and explicitly setting strongly retaining properties to nil? Should I assume all NS and UI framework classes used in properties require explicit deallocs?
它是正确的,我根本不使用ARC时需要写在我的dealloc明确释放属性声明?换句话说,这是真的,以下就不是需要一个明确的dealloc的?
@interface MyClass : NSObject @property (strong, nonatomic) NSObject* myProperty; @end @implementation MyClass @synthesize myProperty; @end
我的下一个更重要的问题来自过渡到 ARC 发行说明文档中的一行:
您不必(实际上不能)释放实例变量,但您可能需要在系统类和其他未使用 ARC 编译的代码上调用 [self setDelegate:nil]。
这就引出了一个问题:我怎么知道哪些系统类不是用 ARC 编译的?我什么时候应该创建自己的 dealloc 并将强保留属性显式设置为 nil?我是否应该假设属性中使用的所有 NS 和 UI 框架类都需要显式解除分配?
There is a wealth of information on SO and elsewhere on the practices of releasing a property's backing ivar when using manual reference tracking, but relatively little about this when using ARC.
在使用手动引用跟踪时,关于 SO 和其他地方的大量关于释放属性支持 ivar 的实践的信息,但在使用 ARC 时相对较少。
回答by Lily Ballard
Short answer: no, you do not have to nil out properties in dealloc
under ARC.
简短回答:不,您不必清除dealloc
ARC 下的属性。
Long answer: You should never nil out properties in dealloc
, even in manual memory management.
长答案:dealloc
即使在手动内存管理中,也不应该将 中的属性置零。
In MRR, you should release your ivars. Nilling out properties means calling setters, which may invoke code that it shouldn't touch in dealloc
(e.g. if your class, or a subclass, overrides the setter). Similarly it may trigger KVO notifications. Releasing the ivar instead avoids these undesired behaviors.
在 MRR 中,您应该释放您的ivars。清除属性意味着调用 setter,这可能会调用它不应该触及的代码dealloc
(例如,如果您的类或子类覆盖了 setter)。同样,它可能会触发 KVO 通知。相反,释放 ivar 可以避免这些不良行为。
In ARC, the system automatically releases any ivars for you, so if that's all you're doing you don't even have to implement dealloc
. However, if you have any non-object ivars that need special handling (e.g. allocated buffers that you need to free()
) you still have to deal with those in dealloc
.
在 ARC 中,系统会自动为您释放任何 ivars,因此如果您只需要这样做,您甚至不必实施dealloc
. 但是,如果您有任何需要特殊处理的非对象变量(例如,您需要分配的缓冲区free()
),您仍然必须处理dealloc
.
Furthermore, if you've set yourself as the delegate of any objects, you should un-set that relationship in dealloc
(this is the bit about calling [obj setDelegate:nil]
). The note about doing this on classes that aren't compiled with ARC is a nod towards weak properties. If the class explicitly marks its delegate
property as weak
then you don't have to do this, because the nature of weak properties means it'll get nilled out for you. However if the property is marked assign
then you should nil it out in your dealloc
, otherwise the class is left with a dangling pointer and will likely crash if it tries to message its delegate. Note that this only applies to non-retained relationships, such as delegates.
此外,如果您已将自己设置为任何对象的委托,则应取消设置该关系dealloc
(这是调用 的一点[obj setDelegate:nil]
)。关于在未使用 ARC 编译的类上执行此操作的说明是对弱属性的一种认可。如果该类明确地将其delegate
属性标记为 asweak
那么您不必这样做,因为弱属性的性质意味着它会被您清除。但是,如果该属性被标记,assign
那么您应该在您的dealloc
. 请注意,这仅适用于非保留关系,例如委托。
回答by C?ur
Just to give the opposite answer...
只是为了给出相反的答案......
Short answer: no, you don't have to nil out auto-synthesized properties in dealloc
under ARC. And you don't have to use the setter for those in init
.
简短回答:不,您不必dealloc
在 ARC 下清除自动合成的属性。而且您不必为init
.
Long answer: You shouldnil out custom-synthesized properties in dealloc
, even under ARC. And you should use the setter for those in init
.
长答案:即使在 ARC 下,您也应该清除 中的自定义合成属性dealloc
。你应该为init
.
The point is your custom-synthesized properties should be safe and symmetrical regarding nullification.
关键是您的自定义合成属性在无效化方面应该是安全且对称的。
A possible setter for a timer:
一个可能的计时器设置器:
-(void)setTimer:(NSTimer *)timer
{
if (timer == _timer)
return;
[timer retain];
[_timer invalidate];
[_timer release];
_timer = timer;
[_timer fire];
}
A possible setter for a scrollview, tableview, webview, textfield, ...:
滚动视图、表格视图、网络视图、文本字段等的可能设置器:
-(void)setScrollView:(UIScrollView *)scrollView
{
if (scrollView == _scrollView)
return;
[scrollView retain];
[_scrollView setDelegate:nil];
[_scrollView release];
_scrollView = scrollView;
[_scrollView setDelegate:self];
}
A possible setter for a KVO property:
KVO 属性的可能设置器:
-(void)setButton:(UIButton *)button
{
if (button == _button)
return;
[button retain];
[_button removeObserver:self forKeyPath:@"tintColor"];
[_button release];
_button = button;
[_button addObserver:self forKeyPath:@"tintColor" options:(NSKeyValueObservingOptions)0 context:NULL];
}
Then you don't have to duplicate any code for dealloc
, didReceiveMemoryWarning
, viewDidUnload
, ... and your property can safely be made public. If you were worried about nil out properties in dealloc
, then it might be time you check again your setters.
这样您就不必为dealloc
, didReceiveMemoryWarning
, viewDidUnload
, ...复制任何代码,并且您的财产可以安全地公开。如果您担心 in 中的属性为零dealloc
,那么您可能是时候再次检查您的 setter 了。