本文介绍了如何使用UnsafeMutablePointer< OpaquePointer>在Swift中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

在某些Core Foundation框架中,如何在Swift中使用UnsafeMutablePointer<OpaquePointer>?为什么要有UnsafeMutablePointer<OpaquePointer>?

How does one use an UnsafeMutablePointer<OpaquePointer> in Swift with some Core Foundation framework? Why have an UnsafeMutablePointer<OpaquePointer>?

给定,一般:一些UnsafeMutablePointer<SomeType>,其中typealias SomeType = OpaquePointer

Given, general: some UnsafeMutablePointer<SomeType> where 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, &currentPrinterOptional!)
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 }

观察到的错误

编译无法运行.似乎(也许)合理的语法无法编译.

上面的示例获得以下(预期的)运行时严重错误:在展开可选值时意外发现nil"..

The above example gets the following (expected) Runtime "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, &currentPrinter)

// Compile Error: Nil cannot initialze specified type 'PMPrinter' (aka 'OpaquePointer')
var currentPrinter: PMPrinter = nil
PMSessionGetCurrentPrinter(printSession, &currentPrinter)

// 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, &currentPrinterOptional!)

资源

Apple:Core Printing⇗
Apple:将Swift与Cocoa和Objective-C结合使用⇗

Resources

Apple: Core Printing ⇗
Apple: Using Swift with Cocoa and Objective-C ⇗

尽管文档提供了有用的信息,但对于UnsafeMutablePointer<PMPrinter>且类型别名为UnsafeMutablePointer<OpaquePointer>UnsafeMutablePointer<PMPrinter>可行实施却难以捉摸.

While the docs have useful information, a workable implementation for UnsafeMutablePointer<PMPrinter> with typealias as UnsafeMutablePointer<OpaquePointer> has been elusive.

推荐答案

PMPrinterPMPaper在PrintCore框架中定义作为指向不完整类型"的指针

PMPrinter and PMPaper are defined in the PrintCore frameworkas pointer to an "incomplete type"

typedef struct OpaquePMPrinter*         PMPrinter;
typedef struct OpaquePMPaper*           PMPaper;

这些作为OpaquePointer导入到Swift中,有点使用起来很麻烦.

Those are imported into Swift as OpaquePointer, and are a bitcumbersome to use.

PMSessionGetCurrentPrinter()的第二个参数是指向的指针非可选 PMPrinter变量,在Swift中必须为在作为inout参数传递之前进行了初始化.一种可能的方式初始化空指针的方法是使用unsafeBitCast.

The second argument to PMSessionGetCurrentPrinter() is a pointer toa non-optional PMPrinter variable, and in Swift it must beinitialized before being passed as an inout argument. One possible wayto initialize a null-pointer is to use unsafeBitCast.

从数组中获取PMPaper对象的最简单方法似乎是是使用CFArrayGetValueAtIndex()而不是将其桥接到斯威夫特数组.返回一个UnsafeRawPointer可以转换的到OpaquePointer.

The easiest way to get the PMPaper objects from the array seems tobe to use CFArrayGetValueAtIndex() instead of bridging it to aSwift array. That returns a UnsafeRawPointer which can be convertedto an OpaquePointer.

这在我的测试中有效:

let printInfo = NSPrintInfo.shared()
let printSession = PMPrintSession(printInfo.pmPrintSession())

var currentPrinter = unsafeBitCast(0, to: PMPrinter.self)
PMSessionGetCurrentPrinter(printSession, &currentPrinter);

var paperListUnmanaged: Unmanaged<CFArray>?
PMPrinterGetPaperList(currentPrinter, &paperListUnmanaged)
guard let paperList = paperListUnmanaged?.takeUnretainedValue() else {
    fatalError()
}
for idx in 0..<CFArrayGetCount(paperList) {
    let paper = PMPaper(CFArrayGetValueAtIndex(paperList, idx))!
    var width = 0.0, height = 0.0
    PMPaperGetWidth(paper, &width)
    PMPaperGetHeight(paper, &height)
    print(width, height)
}

这篇关于如何使用UnsafeMutablePointer&lt; OpaquePointer&gt;在Swift中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-08 06:55