swiftcgeventtap

Crash When Accessing refcon:UnsafeMutableRawPointer? Inside CGEventTap Callback


I have a myCGEventCallback function for CGEventTap that takes parameter "refcon:UnsafeMutableRawPointer?".

I pass my main ViewController as a pointer to the callback using

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

Then inside the callback, I access the ViewController using

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

When the event occurs, the callback works fine. However, it only works 4 times. When the same event occurs for the fifth time, my app crashes, and the debug console just says "LLDB".

It looks like it crashes when I try to access the sender. "sender.someFunction()". It crashes before the function gets to run, so I assume it has a problem accessing the sender.

Is this because of poor memory management? Maybe I need to deallocate the pointer? If so, how and where would I do that?

Thanks!


Solution

  • passRetained(self) increases the retain count for self (which is your view controller instance) by one. Each call to takeRetainedValue() decreases the retain count by one. Those calls must be properly balanced, otherwise the object might be destroyed too early.

    In your case, where the pointer is created once, but used several times in a callback function, you should use the “unretained” conversion in the callback:

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

    so that no ownership is transferred.

    There are two patterns how to create the pointer: