ARC中的系统对象委托是否需要设置为nil? [英] Do system object delegates in ARC need to be set to nil?

查看:113
本文介绍了ARC中的系统对象委托是否需要设置为nil?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

应用有时会崩溃,并显示错误objc_object::release().

An app crashes sometimes with error objc_object::release().

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

The Apple Developer Technical Support mentioned this:

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

Remember that you should always do something like _tableView.delegate = nil; in your -dealloc methods, even if you are using ARC. For compatibility reasons system objects use unsafe_unretained references to implement delegation, instead of the preferred modern replacement weak.

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

Does that mean that I have to set the delegates of system objects to nil when the view controller is about to be released?

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

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

I always assumed UITableView and similar standard objects are using weak references to their delegates?

技术支持部门的示例似乎已过时,因为UITableView已被更新为weak委托.但是,并非所有代表都已更新,例如AVAudioPlayer.delegate仍然是unowned(unsafe).看来苹果公司正在逐步将委托人更新为weak.

It seems that the example by the Technical Support was outdated as UITableView has already been updated to a weak delegate. However not all delegates have been updated, e.g. the AVAudioPlayer.delegate is still unowned(unsafe). It seems that Apple is gradually updating delegates to be weak.

关于委托是否已被手动设置为nil可以简单地通过检查Xcode中的委托声明来确定.如果是weak,请不要打扰.

So as to whether a delegate has been set to nil manually can simply be determined by inspecting the delegate declaration in Xcode. If it is weak, don't bother.

推荐答案

是的,您应该将这些委托设置为nil.

Yes you should set these delegates to nil.

顾名思义,unsafe_unretained引用不会保留您的视图控制器,因此这里没有保留周期或内存泄漏.但是,与weak不同,在取消分配视图控制器时,这些引用不会自动设置为nil.在大多数情况下,这不是问题,因为视图控制器的视图将失效,或者至少在同一时间被释放. 不幸的是,在某些情况下,UIKit也可能会临时保留该视图.这样可以使视图的寿命超过视图控制器,并尝试在已释放对象上调用委托方法,从而导致崩溃.

As suggested by the name, unsafe_unretained references do not retain your view controller so there's no retain cycle or memory leak here. However, unlike weak, these references will not be set to nil automatically when your view controller is deallocated. In most cases this is not a problem as your view controller will outlive its views, or at least be deallocated at the same time. Unfortunately there are a few cases where UIKit may have also temporarily retained the view. This can allow the view to outlive the view controller and attempt to call delegate methods on the deallocated object resulting in a crash.

我所知道的最简单的方法是在滚动仍在滚动时(例如,从滚动条中移除)并取消分配视图控制器,该视图控制器是滚动视图(或其子类之一,如UITableView)的委托.在一长串项目上滑动手势).然后,滚动视图将尝试在已释放的控制器上调用委托方法(如scrollViewDidScroll).

The easiest way I know of to see this in action is to dismiss and deallocate a view controller which is a delegate of a scroll view (or one of its subclasses like UITableView) while the scroll is still scrolling (e.g. from a strong swipe gesture over a long list of items). The scroll view will then attempt to call delegate methods (like scrollViewDidScroll) on the deallocated controller.

这篇关于ARC中的系统对象委托是否需要设置为nil?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆