手動記憶體管理

當與 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 有各自的方法 retainrelease。儘管如此,更希望使用 passRetainedtakeRetainedValue,它們在返回結果之前執行保留:

func preferredFilenameExtension(for uti: String) -> String! {
  let result = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension)
  guard result != nil else { return nil }

  return result!.takeRetainedValue() as String
}

這些解決方案應始終是最後的選擇,語言本地 API 始終是首選。