【问题标题】:Swift: possible removeObserver cyclic reference in addObserverForName's usingBlockSwift:addObserverForName 的 usingBlock 中可能的 removeObserver 循环引用
【发布时间】:2016-06-12 16:26:16
【问题描述】:

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

应用程序委托持有一个类型为 MainWindowController 的数组。监视窗口以查找 NSWindowWillCloseNotification 以便从 MainWindowController 数组中删除控制器。

现在的问题是,如果观察者的移除操作正确——我担心可能会有对 observer 的循环引用,但我不知道如何测试:

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

}

【问题讨论】:

    标签: swift nsnotification


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的提示。我的问题实际上是如何测试是否存在循环引用,但我必须说我的措辞不够具体——我的错。我找到了一种通过在 notificationCenter.debugDescription 中过滤出带有 NSWindowWillCloseNotification 的行来测试它的方法。
    猜你喜欢
    • 2016-11-06
    • 2010-12-09
    • 1970-01-01
    • 1970-01-01
    • 2013-10-22
    • 2021-12-09
    • 2018-09-07
    • 2021-12-01
    • 1970-01-01
    相关资源
    最近更新 更多