我正在尝试学习 iOS 5 中的自动引用计数。现在这个问题的第一部分应该很简单:
使用 ARC 时我不需要在我的 dealloc 中编写显式释放属性语句是否正确?换句话说,以下是否确实不需要显式的dealloc? @interface MyClass : NSObject @property (strong, nonatomic) NSObject* myProperty; @end @implementation MyClass @synthesize myProperty; @end 我的下一个更重要的问题来自 Transitioning to ARC Release Notes 文档中的一行:您不必(实际上不能)释放实例变量,但您可能需要在系统类上调用 [self setDelegate:nil] 和其他未使用 ARC 编译的代码。这就引出了一个问题:我怎么知道哪些系统类不是用 ARC 编译的?我什么时候应该创建自己的 dealloc 并将强保留属性显式设置为 nil?我是否应该假设属性中使用的所有 NS 和 UI 框架类都需要显式释放?
在 SO 和其他地方有大量关于在使用手动引用跟踪时释放属性的支持 ivar 的做法的信息,但在使用 ARC 时,这方面的信息相对较少。
简短回答:不,您不必在 ARC 下清除 dealloc
中的属性。
长答案:您不应该在 dealloc
中清空属性,即使在手动内存管理中也是如此。
在 MRR 中,你应该释放你的 ivars。取消属性意味着调用 setter,这可能会调用它不应该在 dealloc
中触及的代码(例如,如果您的类或子类覆盖了 setter)。同样,它可能会触发 KVO 通知。相反,释放 ivar 可以避免这些不良行为。
在 ARC 中,系统会自动为您释放任何 ivars,因此如果您只这样做,您甚至不必实现 dealloc
。但是,如果您有任何需要特殊处理的非对象 ivars(例如,您需要 free()
分配的缓冲区),您仍然必须处理 dealloc
中的那些。
此外,如果您已将自己设置为任何对象的委托,则应在 dealloc
中取消设置该关系(这是关于调用 [obj setDelegate:nil]
的部分)。关于在未使用 ARC 编译的类上执行此操作的说明是对弱属性的一种认可。如果该类将其 delegate
属性显式标记为 weak
,那么您不必这样做,因为弱属性的性质意味着它将为您取消。但是,如果该属性被标记为 assign
,那么您应该在您的 dealloc
中将其 nil,否则该类将留下一个悬空指针,并且如果它尝试向其委托发送消息,则可能会崩溃。请注意,这仅适用于非保留关系,例如委托。
只是给出相反的答案......
简短回答:不,您不必在 ARC 下的 dealloc
中清除自动合成的属性。而且您不必为 init
中的那些使用设置器。
长答案:您应该在 dealloc
中消除自定义综合属性,即使在 ARC 下也是如此。您应该为 init
中的设置使用设置器。
关键是您的自定义合成属性在无效化方面应该是安全和对称的。
一个可能的定时器设置器:
-(void)setTimer:(NSTimer *)timer
{
if (timer == _timer)
return;
[timer retain];
[_timer invalidate];
[_timer release];
_timer = timer;
[_timer fire];
}
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 属性的可能设置器:
-(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];
}
这样您就不必为 dealloc
、didReceiveMemoryWarning
、viewDidUnload
... 复制任何代码,并且您的财产可以安全地公开。如果您担心 dealloc
中的 nil out 属性,那么可能是时候再次检查您的设置器了。
不定期副业成功案例分享
MyController : UIViewController
类,它创建并拥有一个 UIView 并将视图的委托设置为自身。它是该视图的唯一保留所有者。当控制器被解除分配时,视图也应该被解除分配。那么委托指针是否悬空是否重要?UIWebView
,文档明确声明您需要取消委托。unsafe_unretained
完全等同于assign
属性,并且是 MRR 下委托关系的正常行为,这些需要被取消。