这是我的第一篇文章。我是日本的iOS工程师(这个月刚刚成为)。
我在Swift 5中使用NotificationCenter
的removeObserver
方法时遇到问题。
我通过使用闭包类型addObserver
将观察器添加到ViewController(VC)中。我希望在VC的取消初始化调用时删除此观察器。
我用VC的deinit
方法编写了NotificationCenter.default.removeObserver(self)
。但是,这似乎对我不起作用。
有什么问题吗???
此外,如果我的代码有内存泄漏问题,让我知道如何修复它。
这是我的一段代码。
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: nil) { [weak self] notification in
guard let self = self else { return }
self.loadWeather(notification.object)
}
}
deinit {
print(#function)
print("ViewController died")
NotificationCenter.default.removeObserver(self)
}
}
2条答案
按热度按时间bjg7j2ky1#
Closure-based addObserver的名字
如果你使用addObserver的基于闭包的变体,标记(不是
self
)是观察者。通知中心在这种情况下对self
一无所知。文档对此并不十分清楚。from Twitter
意思是这样做毫无意义:
NotificationCenter.default.removeObserver(self)
docs推荐两种方式:
正常方式
像平常一样订阅:
在代码的某个位置删除观察器。
NotificationCenter.default.removeObserver(self.localeChangeObserver)
,例如通过函数或在deinit
中注意:您仍然需要使用
[weak self]
来避免保留周期。为了避免保留循环,当
self
包含观察者作为强引用时,在块内使用对self
的弱引用。单个订阅
在观察器第一次收到回调后立即删除它
Selector-based addObserver的名字
如果您使用基于选择器的添加,
self
(没有标记)观察器。尽管如此,您应该避免执行以下操作:因为您的代码可能不是添加观察器时涉及对象的唯一代码。删除观察器时,请尽可能使用最具体的详细信息来删除它。例如,如果使用名称和对象来注册观察器,请使用带有名称和对象的
removeObserver(_:name:object:)
。只有在
deinit
方法中调用removeObserver(something)
才是安全的,除此之外,不要使用它,而是使用removeObserver(_:name:object:)
。在
deinit
之外调用removeObserver(self)
是不正确的,因为你会删除所有为该对象设置的观察值。在deinit
之内调用它不是不正确的,但是没有意义,因为该对象会被立即释放。xqnpmsa82#
将观察器对象设置为当前视图控制器。
从apple doc.s,对象为
观察器希望接收其通知的对象;也就是说,只有此发送者发送的通知才会传递给观察者。
正在从
NotificationCenter
移除观察者"另一种方式"
您也可以复制Notification Observer对象,并将其从
deinit
中的NotificationCenter
中删除。