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

时间:2016-06-12 16:26:17

标签: swift nsnotification

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

应用程序委托包含一个键入 MainWindowController 的数组。观察 NSWindowWillCloseNotification 的窗口,以便从 MainWindowController 数组中删除控制器。

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

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)
  }

}

1 个答案:

答案 0 :(得分:0)

通常,您应始终指定merge在使用self注册的块中无主。这将使该块无法强烈引用NSNotificationCenter。您可以使用闭包参数列表前面的捕获列表来执行此操作:

self