ARC下设置委派到零?(Set delegates to nil under ARC?)

2019-07-20 08:04发布

我正在写使用ARC和定位iOS 5以上版本的iOS应用程序。

假设我写了一个代表属性自定义视图对象。 在宣布委托财产,我让一个弱引用,以避免保留周期,因此当实际委托对象(控制器)被破坏,我的自定义视图也将被销毁,具体如下:

@interface MyCustomView : UIView

@property (nonatomic, weak) id<MyCustomViewDelegate> delegate;

@end

一切都很好。

好了,现在我正在写控制器对象,它有两个视图对象的引用:我自定义的视图和苹果提供的UIKit的视图,两者都声明委托性质,而控制器是两种观点的代表。 也许它看起来是这样的:

@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中设置一个或两个代表到零?

我的意思是,我的理解是,在UIKit中视图的委托财产(在这种情况下, tableView )实际上并没有被宣布为一个弱引用,而是一个__unsafe_unretained引用,与iOS的非ARC版的向后兼容性。 所以,也许我需要写

- (void)dealloc
{
    _tableView.dataSource = nil;
    _tableView.delegate = nil;
}

现在,如果我要重写的dealloc,我还没有设置_customView.delegate = nil ,对吧? 因为这是宣布(由我)是一个弱引用,所以应该在销毁被自动设置为无MyViewController

但在另一方面,我不是针对iOS的非ARC的版本,我也不打算。 所以,也许我并不需要在所有覆盖的dealloc?

Answer 1:

设置非弱委托给无通常是一个好主意,除非你知道你不就得了。 对于UITableViewUIScrollView ,我已经经历了以前的iOS版本,下面的步骤崩溃(它可能有助于僵尸运行启用):

  1. 滚动真快。
  2. 按完成或后退按钮或任何驳回VC。

这似乎发生,因为滚动动画被保留到视图的引用,所以认为会超越的VC。 发送滚动事件时崩溃。

我已经驳回含有一个VC后也看到崩溃UIWebView在加载的请求,其中,简单地委托设定为nil是不够的(我认为解决方法是调用[webView loadRequest:nil] )。



Answer 2:

如果只引用说tableView是你唯一的MyViewController控制器,你不需要手动设置UITableViewDelegateUITableViewDataSourcenil

原因是,一旦dealloc上你的方法MyViewController被调用时,tableview中也将与控制器一起被毁(即再次,只要给它的唯一的参考是你唯一的控制器MyViewController类)。

如果你有这个tableview中,其它强引用,如其他控制器,它会那么有可能的是,tableview中可能存在,那么长于MyViewController类。 在这种情况下, 必要对设置UITableViewDelegateUITableViewDataSourcenil在dealloc方法MyViewController因为,正如你提到的,这些性能并不弱引用并不会被自动设置为nil

然而,这种情况在我的经验非常罕见的,但。

大多数时候,我不担心这些设置为nil诚实,但它是一个防御性的编程实践。

看到这个帖子也:

在dealloc方法设置的任何代表为nil需要或不需要



Answer 3:

你会希望将明确设置的唯一原因delegatedataSource ,以nil是,如果customViewtableView可能出生活的视图控制器。 将它们设置为nil会防范delegatedataSource引用解除分配的对象。

如果customViewtableView将与视图控制器一起被释放,没有必要到零了delegatedataSource



文章来源: Set delegates to nil under ARC?