nsevent泄漏以使MACOS中的密钥向下泄漏



在xcode 10.1中使用swift 4.2,当我在nsviewController中添加键入事件的本地监视器时,我的内存泄漏,它可以作为最小版本(无需NIB和NIB和NIB和xib)。

override func loadView() {
    self.view = NSView()
    self.view.wantsLayer = true
}
override func viewDidLoad(){
    super.viewDidLoad
    NSEvent.addLocalMonitorForEvents(matching: .keyDown, handler: handler)
}
lazy var handler:(NSEvent)->NSEvent? = { [ weak self ,unowned picker = picker] event in
    picker.keyDown(with: event)
    return event
}

此内存泄漏没有太多信息:内存泄漏

编辑

在DEINIT方法中称为

deinit {
   NSEvent.removeMonitor(self)
}

编辑2

解决问题:

    override func loadView() {
    self.view = NSView()
    self.view.wantsLayer = true
}
var monitor:Any? // This is essential
override func viewDidLoad(){
    super.viewDidLoad
    monitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown, handler: handler)
}
lazy var handler:(NSEvent)->NSEvent? = { [ weak self ,unowned picker = picker] event in
    picker.keyDown(with: event)
    return event
}
deinit {
   NSEvent.removeMonitor(monitor)
}

来自Apple Docs;

注意

监视器Block用于与蒙版匹配的所有未来事件。您必须致电removeMonitor(_:)以停止监视器。在垃圾收集下,在调用removeMonitor(_:)之前,将不会收集监视器(以及所有块引用)。

这意味着监视器将继续寻找匹配事件,直到调用removeMonitor()为止。因此,您的系统正在使用额外的内存来继续寻找事件,如果您从未调用此事件 - 可能会导致内存相当大。正如它所说的,即使收集垃圾,该对象仍然是分配的 - 因为它正在寻找可以随时发生的事件(因此不能保证将收集这一点)。当您希望系统停止寻找事件时,请确保您致电。

您也可以在handler中做类似的事情。

您可以将事件返回未修改,创建并返回新的NSEVENT对象,或返回零以停止派遣事件。

相关内容

  • 没有找到相关文章

最新更新