Swift:addObserverForName 的 usingBlock 中可能存在 removeObserver 循环引用

标签 swift nsnotification

我正在摆弄一个小型 Swift 应用程序。在其中,用户可以通过单击应用程序菜单中的“新建”来创建任意数量的 MainWindow 实例。

应用程序委托(delegate)保存一个类型为MainWindowController的数组。监 window 口中的 NSWindowWillCloseNotification,以便从 MainWindowController 数组中删除 Controller 。

现在的问题是,观察者的删除是否正确完成 - 我担心可能会有对观察者的循环引用,但我不知道如何测试:

class ApplicationDelegate: NSObject, NSApplicationDelegate {

  private let notificationCenter = NSNotificationCenter.defaultCenter()
  private var mainWindowControllers = [MainWindowController]()

  func newWindow() {
    let mainWindowController = MainWindowController()
    let window = mainWindowController.window
    var observer: AnyObject?
    observer = notificationCenter.addObserverForName(NSWindowWillCloseNotification, 
                                                     object: window,
                                                     queue: nil) { (_) in
            // remove the controller from self.mainWindowControllers
            self.mainWindowControllers = self.mainWindowControllers.filter() {
              $0 !== mainWindowController
            }
            // remove the observer for this mainWindowController.window
            self.notificationCenter.removeObserver(observer!)
    }
    mainWindowControllers.append(mainWindowController)
  }

}

最佳答案

一般来说,您应该始终指定在 NSNotificationCenter 注册的 block 中 self 是无主的。这将防止该 block 对 self 产生强引用。您可以在闭包的参数列表前面使用捕获列表来执行此操作:

{ [unowned self] (_) in
    // Block content
}

关于Swift:addObserverForName 的 usingBlock 中可能存在 removeObserver 循环引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37776568/

相关文章:

ios - 如何使用 Swift 按字母顺序将 TableView 数据分成几部分? (重写)

ios - 在反向 Segue 操作中,选项卡栏在选项卡栏 Controller 上不可见

swift - 观察员从未调用

swift - NSNotificationCenter 将结构作为 UserInfo 的一部分传递

ios - 将 NSNotification 与 CoreData 结合使用

objective-c - NSNotification的测试类型

ios - 访问错误、多线程、GCD、swift

swift - 有没有办法阻止 UILabel 作为 UIView 进行类型检查?

ios - NSNumberFormatter 等价于 stringWithFormat

ios - 将秒转换为小时、分钟和秒