Do system object delegates in ARC need to be set to nil?

痞子三分冷 提交于 2019-12-22 11:19:20

问题


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

The Apple Developer Technical Support mentioned this:

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.

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
   }
}

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


Update:

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.

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.


回答1:


Yes you should set these delegates to nil.

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.

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.



来源:https://stackoverflow.com/questions/46249377/do-system-object-delegates-in-arc-need-to-be-set-to-nil

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!