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

我正在尝试学习 iOS5中的自动参考计数。这个问题的第一部分应该很简单:

  1. 是否正确,我做 没有需要写明确的 当使用 ARC 时,我的 dealloc 中的 release-property 语句 下面的 没有是否需要一个显式的 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:

    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?

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.

33808 次浏览

简短的回答 : 不,您不必去除 ARC 下 dealloc中的属性。

长答案 : 您永远不应该删除 dealloc中的属性,即使在手动内存管理中也是如此。

在 MRR 中,你应该释放你的 伊瓦尔斯。Nillout 属性意味着调用 setter,它可能调用在 dealloc中不应该触及的代码(例如,如果您的类或子类覆盖 setter)。类似地,它可能会触发 KVO 通知。相反,释放 IVAR 可以避免这些不必要的行为。

在 ARC 中,系统会自动为您释放任何变量,所以如果您只是在做这件事,那么您甚至不需要实现 dealloc。但是,如果您有任何需要特殊处理的非对象变量(例如,分配给 free()的缓冲区) ,您仍然需要处理 dealloc中的那些变量。

此外,如果您已经将自己设置为任何对象的委托,则应该在 dealloc中取消设置该关系(这是关于调用 [obj setDelegate:nil]的部分)。关于在没有使用 ARC 编译的类上这样做的说明是对弱属性的肯定。如果类显式地将其 delegate属性标记为 weak,那么您就不必这样做,因为弱属性的性质意味着它将为您取零。但是如果这个属性被标记为 assign,那么你应该在你的 dealloc中取消它,否则这个类会留下一个迷途指针,如果它尝试给它的委托发送消息,它很可能会崩溃。注意,这只适用于非保留关系,如委托。

给出相反的答案。

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中使用 setter。

关键是您的自定义合成属性应该是安全和对称的,关于取消。

一个可能的定时器:

-(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];
}

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. If you were worried about nil out properties in dealloc, then it might be time you check again your setters.