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.