如何在Swift中使用UnsafeMutablePointer<OpaquePointer>
并与一些Core Foundation框架配合?为什么需要UnsafeMutablePointer<OpaquePointer>
?
通常情况下,有一些UnsafeMutablePointer<SomeType>
,其中typealias SomeType = OpaquePointer
具体API示例
// SOURCE: import ApplicationServices.PrintCore
typealias PMPrinter = OpaquePointer
func PMSessionGetCurrentPrinter(_ printSession: PMPrintSession, _ currentPrinter: UnsafeMutablePointer<PMPrinter>)
func PMPrinterGetPaperList(PMPrinter, UnsafeMutablePointer<Unmanaged<CFArray>?>)
特定实例使用情况: 获取打印机支持的纸张列表.
let printInfo = NSPrintInfo.shared()
let printSession = PMPrintSession(printInfo.pmPrintSession())
var currentPrinterOptional: PMPrinter? = nil
PMSessionGetCurrentPrinter(printSession, ¤tPrinterOptional!)
guard let currentPrinter = currentPrinterOptional else { return }
// Get the array of pre-defined PMPapers this printer supports.
// PMPrinterGetPaperList(PMPrinter, UnsafeMutablePointer<Unmanaged<CFArray>?>)
var paperListUnmanaged: Unmanaged<CFArray>?
PMPrinterGetPaperList(currentPrinter, &paperListUnmanaged)
guard let paperList = paperListUnmanaged?.takeUnretainedValue() as [AnyObject]? else { return }
观察到的错误
编译通过的代码未必能够运行。看起来(也许)合理的语法未必能够编译通过。
上面的例子会产生以下(预期的)运行时错误:"fatal error: unexpectedly found nil while unwrapping an Optional value"。
以下是一些尝试:
// Compile Error: Address of variable 'currentPrinter' taken before is is initialized
var currentPrinter: PMPrinter
PMSessionGetCurrentPrinter(printSession, ¤tPrinter)
// Compile Error: Nil cannot initialze specified type 'PMPrinter' (aka 'OpaquePointer')
var currentPrinter: PMPrinter = nil
PMSessionGetCurrentPrinter(printSession, ¤tPrinter)
// Compile Error: Variable 'currentPrinterPtr' used before being initialized
var currentPrinterPtr: UnsafeMutablePointer<PMPrinter>
PMSessionGetCurrentPrinter(printSession, currentPrinterPtr)
// Compile OK: actually compiles
// Runtime Error: unexpectedly found nil while unwrapping an Optional value
var currentPrinterOptional: PMPrinter? = nil
PMSessionGetCurrentPrinter(printSession, ¤tPrinterOptional!)
资源
苹果:核心打印 ⇗
苹果:使用Swift与Cocoa和Objective-C ⇗
虽然文档中有有用的信息,但是对于 typealias 为 UnsafeMutablePointer<OpaquePointer>
的 UnsafeMutablePointer<PMPrinter>
的可行实现一直很难找到。