ARC中的系统对象委托是否需要设置为nil?

应用程序有时会因错误objc_object::release()崩溃。

Apple Developer Technical Support提到了这一点:

请记住,您应该始终执行类似_tableView.delegate = nil; 在-dealloc方法中,即使您使用ARC。 出于兼容性原因,系统对象使用unsafe_unretained引用来实现委派,而不是首选的现代替换weak

这是否意味着我必须在视图控制器即将发布时将系统对象的委托设置为nil?

 class MyViewController: UIViewController { deinit { tableView.delegate = nil tableView.dataSource = nil } } 

我一直认为UITableView和类似的标准对象正在使用对其委托的weak引用?


更新:

似乎技术支持的示例已经过时,因为UITableView已经更新为weak代表。 但是并非所有代表都已更新,例如AVAudioPlayer.delegate仍然是unowned(unsafe) 。 似乎苹果正在逐步更新代表们的weak

因此,通过检查Xcode中的委托声明,可以简单地确定委托是否已手动设置为nil。 如果它weak ,不要打扰。

是的,你应该将这些代表设置nil

正如名称所示, unsafe_unretained引用不会保留您的视图控制器,因此这里没有保留周期或内存泄漏。 但是,与weak不同,当取消分配视图控制器时,这些引用不会自动设置为nil 。 在大多数情况下,这不是问题,因为您的视图控制器将超过其视图,或者至少同时取消分配。 不幸的是,在某些情况下,UIKit可能也暂时保留了该视图。 这可以允许视图比视图控制器更长,并尝试在解除分配的对象上调用委托方法,从而导致崩溃。

我知道看到这个实际操作的最简单的方法是解除并释放一个视图控制器,它是滚动视图(或其子类之一,如UITableView)的委托,同时滚动仍在滚动(例如,从强大的滑动手势很长的项目清单)。 然后,滚动视图将尝试在释放的控制器上调用委托方法(如scrollViewDidScroll )。