是否存在诸如以下代码的强保留问题:

时间:2019-03-26 18:53:25

标签: ios swift

在下面的代码中,self.tableView.reloadData()中的self是否作为强引用存在问题,应该将其更改为弱引用,还是可以这样?

class SomeViewController : UIViewController {
    fileprivate var notificationToken: NotificationToken?  = nil


...
    override func viewDidLoad()
    {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(onNotification), name: NSNotification.Name(SomeNotification), object: nil)

        realmNotificationToken = blockedList.observe({ (changes: RealmCollectionChange) in
            switch changes
            {
            case .initial:
                self.tableView.reloadData() // Case 1
                break
...


    @objc func onNotification()
    {
        DispatchQueue.main.async{
            self.tableView.reloadData() // Case 2
        }
    }

在这两个示例中,由于self是强引用,因此保留周期是否存在任何问题,应该将其更改为弱引用? 在这两种情况下,使用self.tableView.reloadData()的两个块的寿命是多少?如果一生都是短暂的,那么使用强壮没有问题,这些块寿命长吗?

1 个答案:

答案 0 :(得分:1)

案例2是一个不可逃脱的闭包,因此没有问题。

案例1是@escaping,因此您需要使用weakunowned引用。 @escaping表示您正在将闭包传递给可能比创建闭包的对象(即您的ViewController)更持久的对象。如果您在self中强烈捕获@escaping,则ViewController现在的生存时间与闭包寿命一样长,并且闭包寿命一直到取消订阅为止。如果您仅在ViewController取消初始化时取消订阅,则现在有一个循环。因为订阅永远不会死,而闭包永远不会被释放,而ViewController也不会因为订阅永不死,所以它不会被释放。

编辑: 我要补充一点,无论哪种情况,您实际上都不需要自我。您可以简单地捕获tableview(如果将其隐式展开,则将其分解为一个普通的可选对象,这很好):

realmNotificationToken = blockedList.observe({ [tableView] (changes: RealmCollectionChange) in
   switch changes {
   case .initial:
      tableView?.reloadData()