在ARC下将代表设置为nil? [英] Set delegates to nil under ARC?
问题描述
我正在使用ARC编写iOS应用,并定位到iOS 5 +.
I'm writing iOS apps using ARC and targeting iOS 5+.
假设我编写了一个具有委托属性的自定义视图对象.在声明委托属性时,我将其作为弱引用以避免保留周期,以便当实际的委托对象(控制器)被销毁时,我的自定义视图也将被销毁,如下所示:
Suppose I write a custom view object that has a delegate property. In declaring the delegate property, I make it a weak reference to avoid a retain cycle, so that when the actual delegate object (the controller) is destroyed, my custom view will also be destroyed, as follows:
@interface MyCustomView : UIView
@property (nonatomic, weak) id<MyCustomViewDelegate> delegate;
@end
一切都很好.
好吧,所以现在我在编写控制器对象,它引用了两个视图对象:我的自定义视图和Apple提供的UIKit视图,这两个都声明了委托属性,而控制器是这两个的委托意见.也许看起来像这样:
Ok, so now I'm writing the controller object, and it has references to two view objects: my custom view and an Apple-supplied UIKit view, both of which declare delegate properties, and the controller is the delegate for both views. Maybe it looks something like this:
@interface MyViewController : UIViewController <MyCustomViewDelegate, UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) MyCustomView *customView;
@property (nonatomic, strong) UITableView *tableView;
@end
@implementation MyViewController
- (void)viewDidLoad
{
self.customView.delegate = self;
self.tableView.dataSource = self;
self.tableView.delegate = self;
}
@end
我的问题是:我是否需要重写dealloc来将一个或两个委托都设置为nil?
My question is this: Do I need to override dealloc to set either or both delegates to nil?
我的意思是,据我所知,实际上,UIKit视图的委托属性(在本例中为tableView
)并不是声明为弱引用,而是声明为__unsafe_unretained
引用,以实现与...的向后兼容性.非ARC版本的iOS.所以也许我需要写
I mean, as I understand it, the delegate property of the UIKit view (in this case, tableView
) isn't actually declared to be a weak reference, but rather an __unsafe_unretained
reference, for backwards compatibility with non-ARC version of iOS. So maybe I need to write
- (void)dealloc
{
_tableView.dataSource = nil;
_tableView.delegate = nil;
}
现在,如果我必须重写dealloc,我仍然不必设置_customView.delegate = nil
,对吗?由于(我)宣布该值为弱引用,因此在MyViewController
销毁后应将其自动设置为nil.
Now, if I do have to override dealloc, I still don't have to set _customView.delegate = nil
, right? Because that was declared (by me) to be a weak reference, so it should be set to nil automatically upon the destruction of MyViewController
.
但是,另一方面,我的目标不是非ARC版本的iOS,也不是我打算的目标.所以也许我根本不需要重写dealloc?
But on the other hand, I'm not targeting non-ARC versions of iOS, nor do I intend to. So maybe I don't need to override dealloc at all?
推荐答案
将非弱委托设置为nil通常是一个好主意,除非您知道不必这样做.对于UITableView
和UIScrollView
,我在iOS以前的版本上经历了以下步骤的崩溃(可能会在启用僵尸的情况下运行):
Setting non-weak delegates to nil is generally a good idea unless you know you don't have to. For UITableView
and UIScrollView
, I've experienced crashes on previous iOS versions with the following steps (it may help to run with zombies enabled):
- 滚动非常快.
- 按[完成]或返回按钮或任何其他方法可关闭VC.
这似乎是由于滚动动画保留了对视图的引用而导致的,因此视图的寿命超过了VC.发送滚动事件时崩溃.
This appears to happen because the scrolling animation is retaining a reference to the view, so the view outlives the VC. It crashes when sending the scroll event.
在加载请求时,关闭包含UIWebView
的VC后,我也看到了崩溃,在该VC中,仅将委托设置为nil是不够的(我认为解决方法是调用[webView loadRequest:nil]
).
I've also seen crashes after dismissing a VC containing a UIWebView
while a request is being loaded, where simply setting the delegate to nil was not sufficient (I think the workaround was to call [webView loadRequest:nil]
).
这篇关于在ARC下将代表设置为nil?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!