简体   繁体   English

使用ARC时,我是否在dealloc中将属性设置为nil?

[英]Do I set properties to nil in dealloc when using ARC?

I am trying to learn Automatic Reference Counting in iOS 5. Now the first part of this question should be easy: 我正在尝试学习iOS 5中的自动引用计数。现在这个问题的第一部分应该很简单:

  1. Is it correct that I do NOT need to write explicit release-property statements in my dealloc when using ARC? 它是正确的,使用ARC时,我不需要写在我的dealloc明确释放属性声明? In other words, is it true that the following does NOT need a explicit dealloc? 换句话说,这是真的,以下不需要明确的dealloc的?

     @interface MyClass : NSObject @property (strong, nonatomic) NSObject* myProperty; @end @implementation MyClass @synthesize myProperty; @end 
  2. My next and more important question comes from a line in the Transitioning to ARC Release Notes document: 我的下一个也是更重要的问题来自“ 转换为ARC发行说明”文档中的一行:

    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. 您不必(实际上不能)释放实例变量,但您可能需要在系统类和其他未使用ARC编译的代码上调用[self setDelegate:nil]。

    This begs the question: how do I know which system classes are not compiled with ARC? 这引出了一个问题:我怎么知道哪些系统类没有用ARC编译? When should I be creating my own dealloc and explicitly setting strongly retaining properties to nil? 我什么时候应该创建自己的dealloc并明确地将强保留属性设置为nil? Should I assume all NS and UI framework classes used in properties require explicit deallocs? 我应该假设属性中使用的所有NS和UI框架类都需要显式的deallocs吗?

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时相对较少。

Short answer : no, you do not have to nil out properties in dealloc under ARC. 简短的回答 :不,你不必在ARC下的dealloc删除属性。

Long answer : You should never nil out properties in dealloc , even in manual memory management. 答案很长 :即使在手动内存管理中,也不应该在dealloc删除属性。

In MRR, you should release your ivars . 在MRR中,您应该释放您的ivars Nilling out properties means calling setters, which may invoke code that it shouldn't touch in dealloc (eg if your class, or a subclass, overrides the setter). Nilling out属性意味着调用setter,它可以调用不应该在dealloc触及的代码(例如,如果你的类或子类覆盖setter)。 Similarly it may trigger KVO notifications. 同样,它可能会触发KVO通知。 Releasing the ivar instead avoids these undesired behaviors. 释放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 . 在ARC中,系统会自动为您释放任何ivars,因此,如果这就是您所做的一切,您甚至不必实现dealloc However, if you have any non-object ivars that need special handling (eg allocated buffers that you need to free() ) you still have to deal with those in dealloc . 但是,如果您有任何需要特殊处理的非对象ivars(例如,您需要free()分配缓冲区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] ). 此外,如果您将自己设置为任何对象的委托,则应该在dealloc取消设置该关系(这是关于调用[obj setDelegate:nil] )。 The note about doing this on classes that aren't compiled with ARC is a nod towards weak properties. 关于在未使用ARC编译的类上执行此操作的说明是对弱属性的认可。 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. 如果类明确地将其delegate属性标记为weak那么您不必执行此操作,因为弱属性的性质意味着它将为您填写。 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. 但是如果属性被标记为assign那么你应该在你的dealloc中将它取出来,否则该类会留下一个悬空指针,如果它试图向其委托发送消息,它可能会崩溃。 Note that this only applies to non-retained relationships, such as delegates. 请注意,这仅适用于非保留关系,例如委托。

Just to give the opposite answer... 只是给出相反的答案......

Short answer : no, you don't have to nil out auto-synthesized properties in dealloc under ARC. 简短的回答 :不,你不必在ARC下的dealloc自动合成属性。 And you don't have to use the setter for those in init . 而且你不必在init使用setter。

Long answer : You should nil out custom-synthesized properties in dealloc , even under ARC. 答案很长 :即使在ARC下,你也应该dealloc找出自定义合成的属性。 And you should use the setter for those in init . 你应该在init使用setter。

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, ...: 滚动视图,tableview,webview,textfield,...的可能setter:

-(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属性的setter:

-(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. 然后,您不必为deallocdidReceiveMemoryWarningviewDidUnload ,...复制任何代码,并且您的财产可以安全地公开。 If you were worried about nil out properties in dealloc , then it might be time you check again your setters. 如果你担心dealloc nil属性,那么你可能需要再次检查你的setter。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM