Search code examples
iosswiftswift2owncloudunsafemutablepointer

How to get the AutoreleasingUnsafeMutablePointer of a Swift Object


I'm currently the owncloud iOS library for an upload task of my Swift app. It is written in Objective-C and requires me to pass an AutoreleasingUnsafeMutablePointer<NSProgress?> to the upload method.

Say I create a new object like so

let progress: NSProgress? = NSProgress()

How can I get the AutoreleasingUnsafeMutablePointer<NSProgress?> of this object in Swift?

I tried it the following way:

var progress: NSProgress? = NSProgress()
let unsafeAutoreleasingProgressPointer = AutoreleasingUnsafeMutablePointer<NSProgress?>.init(&progress)

But I get an

EXC_BAD_ACCESS (code=1, address = 0x15942320)

when executing the code. I would like to keep a reference to the progress object because I want to add an observer callback that tells me the upload progress in percent (as also demonstrated in the example link).


Solution

  • There were 2 issues in fact.

    We can create an AutoreleasingUnsafeMutablePointer<NSProgress?> object like so:

    let progress = NSProgress()
    let progressPointer = AutoreleasingUnsafeMutablePointer<NSProgress?>.init(&progress)
    

    It's important to note that you have to keep the pointer around. If you create the pointer in a method, the reference to it will be lost as soon as we exit the method scope. This causes the

    EXC_BAD_ACCESS

    exception. So your implementation might look like this:

    class MyClass: NSObject {
        dynamic var progress: NSProgress = NSProgress()
        var progressPointer: AutoreleasingUnsafeMutablePointer<NSProgress?> = nil
    
        override init(){
            //...
            //init non optional variables here
            super.init()
            progressPointer = AutoreleasingUnsafeMutablePointer<NSProgress?>.init(&progress)
        }
    }
    

    In my case I did Key-Value Observing because I was using a third party Objective C dependency. Note that you have to put the dynamic keyword in front of the object you want to observe using KVO.

    If you still get an

    EXC_BAD_ACCESS

    exception, use the Singleton pattern.