swiftxcode7cfrunloop

Using UnsafeMutablePointer and CFRunLoopObserverContext in swift 2


I have the following bit of code

private func addRunLoopObserverForSaving() {
    var _self = self

    withUnsafeMutablePointer(&_self) { (pSelf) -> Void in
        var observerContext = CFRunLoopObserverContext(
            version: 0,
            info: pSelf,
            retain: nil,
            release: nil,
            copyDescription: nil)

        withUnsafeMutablePointer(&observerContext, { (pObserverContext) -> Void in

            let observer = CFRunLoopObserverCreate(
                kCFAllocatorDefault,
                CFRunLoopActivity.BeforeTimers.rawValue,
                true,
                0,
                { (observer, activity, context) -> Void in
                    guard context != nil else { return }

                    let pObserverContext = UnsafeMutablePointer<CFRunLoopObserverContext>(context)
                    let pGraphsModel = UnsafeMutablePointer<GraphsModel>(pObserverContext.memory.info)

                    let z = pGraphsModel.memory
                    ...
                },
                pObserverContext
            )

            CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode)
        })
    }
}

For some reasons, line z = pGraphsModel.memory always give me a EXC_BAD_ACCESS. I am not sure if I am using UnsafeMutablePointer correctly when retrieving the stored value. Any thoughts are appreciated!

PS. This happened on XCode 7 beta5.


Solution

  • Fixed it myself, it turned out context in the callback is actually the observer context's info member. So instead of:

    let pObserverContext = UnsafeMutablePointer<CFRunLoopObserverContext>(context)
    let pGraphsModel = UnsafeMutablePointer<GraphsModel>(pObserverContext.memory.info)
    
    let z = pGraphsModel.memory
    ...
    

    It should simply be

    let pGraphsModel = UnsafeMutablePointer<GraphsModel>(context)
    
    let z = pGraphsModel.memory
    ...