【问题标题】:Crash When Accessing refcon:UnsafeMutableRawPointer? Inside CGEventTap Callback访问 refcon:UnsafeMutableRawPointer 时崩溃? CGEventTap 回调内部
【发布时间】:2018-10-30 13:17:54
【问题描述】:

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

我将主 ViewController 作为指向回调的指针传递给使用

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

然后在回调中,我使用

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

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

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

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

谢谢!

【问题讨论】:

  • takeRetainedValue() 执行对象的释放,因此您不应在仅保留一次的对象上多次调用它。你可能想要做的是在你的回调中使用takeUnretainedValue(),然后当你知道回调不能再被调用时使用.release()——例如见stackoverflow.com/a/44215903/2976878

标签: swift cgeventtap


【解决方案1】:

passRetained(self) 增加 self 的保留计数(这是您的 查看控制器实例)一个。每次拨打takeRetainedValue() 都会减少 保留计数减一。这些呼叫必须适当平衡,否则 该对象可能被过早地销毁。

在您的情况下,指针被创建一次,但在 回调函数,您应该使用“未保留”转换 回调:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多