Member-only story
Manual Memory Management in Swift (iOS)
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:
a.b = b // a retains b
b.a = a // b holds a weak reference to a -- not a reference cyclesetupDisplayLink() {
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:
These solutions should always be the last resort, and language-native APIs sould always be preferred.
func preferredFilenameExtension(for uti: String) -> String! {
let result = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension)
guard result != nil else { return nil }return result!.takeRetainedValue() as String
}