手动内存管理
当与 C API 接口时,可能想要退出 Swift 引用计数器。这样做是通过非托管对象实现的。
如果需要提供一个 C 型函数的类型惩罚指针,请使用 Unmanaged 结构的 toOpaque 方法获取原始指针,并使用 fromOpaque 恢复原始实例:
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()
}
请注意,如果使用 passUnretained 和对应物,则必须采取与 unowned 参考相同的所有预防措施。
要与传统的 Objective-C API 进行交互,可能需要手动影响某个对象的引用计数。因为 Unmanaged 有各自的方法 retain 和 release。尽管如此,更希望使用 passRetained 和 takeRetainedValue,它们在返回结果之前执行保留:
func preferredFilenameExtension(for uti: String) -> String! {
let result = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension)
guard result != nil else { return nil }
return result!.takeRetainedValue() as String
}
这些解决方案应始终是最后的选择,语言本地 API 始终是首选。