为什么不在使用NSNotificationCenter的对象上调用deist,我在下面包含了我的代码的简单版本.在我创建一个观察通知的对象以及触发通知时,它会删除观察者的订阅.如果释放了对象,我也会删除订阅.但是,在为应用程序运行性能分析时,您可以看到在viewDidAppear完成后,测试对象的持久分配现在为零,应该已经释放.为什么会这样?
import UIKit class ViewController: UIViewController { var t: test? override func viewWillAppear(animated: Bool) { t = test() fire() t = nil } func fire() { NSNotificationCenter.defaultCenter().postNotificationName("Hello", object: nil) } } class test { var e: NSObjectProtocol? init() { e = NSNotificationCenter.defaultCenter().addObserverForName( "Hello", object: nil, queue: NSOperationQueue.mainQueue(), usingBlock: sayHello) } deinit { if let e = e { NSNotificationCenter.defaultCenter().removeObserver(e) } } func sayHello(notification: NSNotification) { if let e = e { NSNotificationCenter.defaultCenter().removeObserver(e) } } }
即使在Objective-C中,我也会很感激,因为它也可能会回答这个问题.
非常感谢你
传递self
作为闭包参数的函数将创建保留周期.你正在做的是有效率的短手:
init() { e = NSNotificationCenter.defaultCenter().addObserverForName("Hello", object: nil, queue: NSOperationQueue.mainQueue() { notification in self.sayHello(notification) } }
正如你所看到self
的那样被捕获.为了解决这个问题,你应该定义self
为unowned
在捕获列表:
init() { e = NSNotificationCenter.defaultCenter().addObserverForName("Hello", object: nil, queue: NSOperationQueue.mainQueue() { [unowned self] notification in self.sayHello(notification) } }
这将阻止保留周期.
正如您删除观察者sayHello
,你也应该设置e
到nil
在那里移除观察者后了.
有关使用此方法时保留周期,捕获等的详细信息,请参阅此问题NSNotificationCenter
.