访问refcon:UnsafeMutableRawPointer时崩溃?内部CGEventTap回调

时间:2018-10-30 13:17:54

标签: swift cgeventtap

我有一个用于CGEventTap的myCGEventCallback函数,该函数带有参数“ refcon:UnsafeMutableRawPointer?”。

我使用

将主ViewController作为指向回调的指针传递
let pointer = UnsafeMutableRawPointer(Unmanaged.passRetained(self).toOpaque())

然后在回调中,我使用

访问ViewController
let sender:ViewController = Unmanaged<T>.fromOpaque(refcon!).takeRetainedValue()

事件发生时,回调工作正常。但是,它只能工作4次。第五次发生相同事件时,我的应用程序崩溃,并且调试控制台仅显示“ LLDB”。

当我尝试访问发件人时,它似乎崩溃了。 “ sender.someFunction()”。该函数在运行之前崩溃,因此我认为它在访问发送者时有问题。

这是因为内存管理不善吗?也许我需要取消分配指针?如果是这样,我将如何以及在哪里做?

谢谢!

1 个答案:

答案 0 :(得分:1)

passRetained(self)增加了self的保留计数(这是您的 查看控制器实例)。对takeRetainedValue()的每次通话都会减少 保留数加1。这些通话必须适当平衡,否则 该物体可能为时过早。

在您的情况下,指针仅创建一次,但在其中多次使用 回调函数,您应该在 回调:

let sender = Unmanaged<ViewController>.fromOpaque(refcon!).takeUnretainedValue()

因此不会转让所有权。

有两种创建指针的模式:

  • 如果保证回调仅在生命周期内处于活动状态 的视图控制器,然后您可以创建指针而无需保留 实例:

    let pointer = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())
    
  • 否则,如果视图控制器实例应保持活动状态 在回调处于活动状态时,请在创建指针时保留它

    let pointer = UnsafeMutableRawPointer(Unmanaged.passRetained(self).toOpaque())
    

    并在回调不再活动时最终释放它:

    Unmanaged<ViewController>.fromOpaque(pointer).release()