首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSEvent在macOS中的密钥泄漏

NSEvent在macOS中的密钥泄漏
EN

Stack Overflow用户
提问于 2019-03-11 14:52:21
回答 1查看 755关注 0票数 1

在使用SWIFT4.2的Xcode 10.1中,当我在我的NSViewController中为按键事件添加一个本地监视器时,内存泄漏,它被作为最小版本(没有nib和xib)来运行。

代码语言:javascript
复制
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方法中,removeMonitor被称为

代码语言:javascript
复制
deinit {
   NSEvent.removeMonitor(self)
}

编辑2

解决问题:

代码语言:javascript
复制
    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)
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-11 15:07:37

来自苹果文档

备注 对于所有匹配掩码的未来事件,都会调用监视器Block。您必须调用removeMonitor(_:)来停止监视器。在垃圾收集下,在调用removeMonitor(_:)之前,将不会收集监视器(以及块引用的所有内容)。

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

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

您可以不修改地返回事件,创建和返回一个新的NSEvent对象,或者返回零来停止事件的分派。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55104573

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档