我应该在哪里删除Swift中NSNotification
的观察者,因为viewDidUnload
和dealloc()
不可用?
答案 0 :(得分:95)
从 iOS 9 (以及OS X 10.11)开始,如果您不使用基于块的,则不需要自行删除观察者观察者虽然。系统将为您完成,因为它可以为观察者使用归零弱引用。
如果您使用的是基于块的观察者,请确保在闭包的捕获列表中使用[weak self]
自我捕获,然后删除观察者在deinit
方法中。如果您不使用弱引用自我,则永远不会调用deinit
方法(从而删除该观察者),因为通知中心将无限期地对其进行强有力的引用。
可以在Foundation Release Notes for OS X v10.11 and iOS 9找到更多信息。
如果观察者能够存储为归零弱引用,则底层存储将把观察者存储为归零弱引用,或者如果对象不能被弱存储(即它具有自定义保留/释放机制,那么防止运行时能够以弱方式存储对象)它会将对象存储为非弱的归零引用。这意味着观察者不需要在他们的释放方法中取消注册。
基于块的观察者通过 - [NSNotificationCenter addObserverForName:object:queue:usingBlock]方法仍然需要在不再使用时取消注册,因为系统仍然拥有对这些观察者的强引用。
答案 1 :(得分:60)
使用以下方法,其功能与dealloc
相同。
deinit {
// Release all resources
// perform the deinitialization
}
在取消分配类实例之前立即调用deinitializer。您使用deinit关键字编写deinitializers,类似于使用init关键字编写初始化器的方式。 Deinitializers仅适用于班级类型。
<强> Swift Deinitializer 强>
答案 2 :(得分:44)
您可以使用三种方法:
1 - 在popViewController
之后,返回navigationController
或dismissViewControllerAnimated
:
deinit {
print("Remove NotificationCenter Deinit")
NSNotificationCenter.defaultCenter().removeObserver(self)
}
或
2 - viewDidDisappear
,在它已经是下一个视图控制器后删除:
override func viewDidDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
或
3 - viewWillDisappear
- 在打开下一个视图之前:
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
Swift 3.0语法:
NotificationCenter.default.removeObserver(self)
答案 3 :(得分:9)
在Swift 4.2中,这是删除观察者的方法之一
(?<=[0-9A-Za-z]+\s*)=
在viewDidLoad类中设置addObserver通知
deinit {
NotificationCenter.default.removeObserver(self, name: Notification.Name.Identifier, object: nil)
}
答案 4 :(得分:3)
Swift提供了一个deinit方法,在类被破坏之前调用它们。
答案 5 :(得分:2)
我还想指出你应该使用这种方法:
func addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name?, object anObject: Any?)
而不是
func addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping (Notification) -> Void) -> NSObjectProtocol
后者不会删除观察者(最近遇到这个问题)。如果您使用iOS9,前者将删除观察者。
答案 6 :(得分:0)
如果您将观察者添加到viewWillAppear()
并将其移除viewWillDisappear()
答案 7 :(得分:0)
deinit {
NotificationCenter.default.removeObserver(self)
}
答案 8 :(得分:0)
快捷键5
我有一个聊天应用程序,所以每当我从ChatLogViewController转到其他viewController然后又回来时,我的键盘通知都会有1个额外的Observer。为了消除这种情况,我在更改viewController 或从chatLogViewController 中消失时删除了所有观察者。
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.removeObserver(self)
}