手动内存管理
当与 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 始终是首选。