Manual Memory Management

suggest change

When interfacing with C APIs, one might want to back off Swift reference counter. Doing so is achieved with unmanaged objects.

If you need to supply a type-punned pointer to a C function, use toOpaque method of the Unmanaged structure to obtain a raw pointer, and fromOpaque to recover the original instance:

setupDisplayLink() {
  let pointerToSelf: UnsafeRawPointer = Unmanaged.passUnretained(self).toOpaque()
  CVDisplayLinkSetOutputCallback(self.displayLink, self.redraw, pointerToSelf)
}

func redraw(pointerToSelf: UnsafeRawPointer, /* args omitted */) {
  let recoveredSelf = Unmanaged<Self>.fromOpaque(pointerToSelf).takeUnretainedValue()
  recoveredSelf.doRedraw()
}

Note that, if using passUnretained and counterparts, it’s necessary to take all precautions as with unowned references.

To interact with legacy Objective-C APIs, one might want to manually affect reference count of a certain object. For that Unmanaged has respective methods retain and release. Nonetheless, it is more desired to use passRetained and takeRetainedValue, which perform retaining before returning the result:

func preferredFilenameExtension(for uti: String) -> String! {
  let result = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension)
  guard result != nil else { return nil }

  return result!.takeRetainedValue() as String
}

These solutions should always be the last resort, and language-native APIs sould always be preferred.

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:



Table Of Contents