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

2024-04-06

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

苹果开发者技术支持提到了这一点:

请记住,您应该始终执行类似 _tableView.delegate 的操作 = 零;在你的 -dealloc 方法中,即使你使用的是 ARC。出于兼容性原因系统对象使用unsafe_unretained参考实施委托,而不是首选的现代 替代品weak.

这是否意味着当视图控制器即将被释放时,我必须将系统对象的委托设置为 nil ?

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

我一直以为UITableView和类似的标准对象正在使用weak提及他们的代表?


Update:

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

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


是的,您应该将这些代表设置为nil.

正如名字所暗示的那样,unsafe_unretained引用不会保留您的视图控制器,因此这里没有保留周期或内存泄漏。然而,与weak,这些引用不会被设置为nil当你的视图控制器被释放时自动。在大多数情况下,这不是问题,因为您的视图控制器将比其视图更长寿,或者至少同时被释放。 不幸的是,在某些情况下,UIKit 可能也暂时保留了视图。这可能会导致视图比视图控制器的寿命更长,并尝试在已释放的对象上调用委托方法,从而导致崩溃。

据我所知,要看到这一点,最简单的方法是在滚动仍在滚动时(例如,通过强烈的滑动手势)关闭并取消分配一个视图控制器,该视图控制器是滚动视图(或其子类之一,如 UITableView)的委托。一长串项目)。然后滚动视图将尝试调用委托方法(例如scrollViewDidScroll)在已释放的控制器上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐