手動記憶體管理
當與 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 始終是首選。