将代表设置为ARC下的零?

我正在使用ARC编写iOS应用程序,并定位iOS 5+。

假设我写了一个具有委托属性的自定义视图对象。 在声明委托属性时,我把它作为避免保留循环的弱引用,以便在实际委托对象(控制器)被销毁时,我的自定义视图也将被销毁,如下所示:

@interface MyCustomView : UIView @property (nonatomic, weak) id<MyCustomViewDelegate> delegate; @end 

一切都很好。

好了,现在我正在编写控制器对象,并且它引用了两个视图对象:我的自定义视图和Apple提供的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引用,用于向后兼容非ARC版本的iOS。 所以也许我需要写

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

现在,如果我必须重写dealloc,我仍然不需要设置_customView.delegate = nil ,对吧? 因为这是(我)宣布是一个弱引用,所以它应该被设置为零自动销毁MyViewController

但另一方面,我不是针对iOS的非ARC版本,也不打算。 所以也许我不需要重写dealloc呢?

把非弱代表设置为零通常是一个好主意,除非你知道你不需要。 对于UITableViewUIScrollView ,我已经遇到以前的iOS版本的崩溃,以下步骤(这可能有助于运行僵尸启用):

  1. 滚动真的很快。
  2. 按下“完成”或后退button或其他任何closuresVC。

这似乎是因为滚动animation保留了对视图的引用,所以视图超出了VC。 发送滚动事件时发生崩溃。

我也看到在请求被加载的时候closures包含UIWebView的VC之后崩溃,只是简单地将代理设置为nil是不够的(我想解决方法是调用[webView loadRequest:nil] )。

如果对tableView唯一的引用是你唯一的MyViewController控制器,你不需要手动设置UITableViewDelegateUITableViewDataSource nil

原因是一旦你的MyViewController上的dealloc方法被调用,tableview也会随着控制器一起被销毁(也就是说,只要它唯一的引用是你唯一的控制器MyViewController类)。

如果你有其他强大的引用到这个tableview,比如其他控制器,那么tableview可能会比MyViewController类存在更长的时间。 在这种情况下,需要将UITableViewDelegateUITableViewDataSource设置为MyViewController的dealloc方法中的nil ,因为正如您所提到的,这些属性不是弱引用,不会自动设置为nil

不过,这种情况在我的经验中很less见。

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

也看到这个post:

在dealloc方法中设置任何委托为零是需要或不需要的

你想显式设置delegatedataSource nil的唯一原因是,如果自customView或表视图可能出现在视图控制器。 将它们设置为nil将防止引用释放对象的delegatedataSource

如果customViewtableView将与视图控制器一起解除分配,则不需要清除delegatedataSource