【问题标题】:Should notifications be removed using removeObserver(self) in iOS?是否应该在 iOS 中使用 removeObserver(self) 删除通知?
【发布时间】:2020-02-19 18:36:54
【问题描述】:

是否应该在 iOS 中使用 self 删除通知?

队友在viewWillAppear注册了一个通知,在viewDidDisappear删除了like,

override func viewWillAppear(_ animated: Bool) {
    NotificationCenter.default.addObserver(self, selector: #selector(onDidReceiveData(_:)), name: .didReceiveData, object: API.shared)
}

override func viewDidDisappear(_ animated: Bool) {
    NotificationCenter.default.removeObserver(self)
}

在审核时,我已评论并建议删除带有 explicit name 的通知,而不是使用 self 删除的通知,因为我认为将来可能需要在 viewWillLoad 不应受到意外或开发人员错误调用 NotificationCenter.default.removeObserver(self) 的影响。我的建议是删除观察者使用,

override func viewDidDisappear(_ animated: Bool) {
    NotificationCenter.default.removeObserver(self, name:.didReceiveData, object: nil)
}

队友回复说用NotificationCenter.default.removeObserver(self)删除是完全可以的,因为我们暂时没有注册其他通知。我正在寻求参考或指导来说服他,为什么使用名称而不是 self 明确删除通知很重要。

Apple 有没有关于移除通知观察者的最佳做法的指南?

【问题讨论】:

  • 我看到了类似的东西,如果我们在选择器方法中使用弱引用,我们不需要删除通知观察者。我不确定。关注此线程以了解更新。
  • Apple 在文档中特别声明了以下内容:“删除观察者时,请尽可能详细地删除它。例如,如果您使用名称和对象来注册观察者,请使用 removeObserver( _:name:object:) 带有名称和对象。”

标签: ios swift design-patterns notifications nsnotificationcenter


【解决方案1】:

在 iOS 9 之后,无需移除观察者,因为 iOS 会从取消分配的 ViewController 中移除观察者

【讨论】:

  • 但是如果在 viewWillDisappear 中使用 removeObserver(self) ,即使视图控制器存在于堆栈中但不在顶部,观察者也不会响应。这就是问题所在。
  • 这并没有回答我提出的实际问题。
【解决方案2】:

问题是删除viewWillDisappear 中的所有通知是不安全的。出于明显的原因,这不是一个好习惯,但没有记录在案。 在 iOS 9 之后,不需要调用 removeObserver,因为 iOS 不会尝试通知已释放的对象。在您的情况下,即使视图控制器不可见但存在于导航堆栈中,您也想听 你应该在deinit

    class ViewController: UIViewController {
    deinit {
     NotificationCenter.default.removeObserver(self, name:.didReceiveData, object: nil)
    }
   }

【讨论】:

  • 这并没有回答我提出的实际问题。
  • 这个答案无法说服我的队友。请阅读帖子以了解实际问题。
  • 问题是删除viewWillDisappear 中的所有通知是不安全的。这是一种做法,因此没有记录在案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多