Swift3 更改为 UnsafeMutablePointer

Swift3 changes to UnsafeMutablePointer

我正在将我的一个 iOS 应用程序移植到 Swift3 / Xcode8。 我嵌入了一个 C 库,它需要一个函数参数类型:

char ***

在 Swift2.3 中,这被翻译成:

UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<Int8>>>

所以我可以在我的 swift 代码中这样声明该指针:

let myPointer = UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<Int8>>>.alloc(1)

在我使用 Swift3 更新到 Xcode8 之前,它运行良好,现在我遇到编译器错误:

Cannot convert value of type 'UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<Int8>>>' to expected argument type 'UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>?>!'

有人可以帮助我了解 swift3 中的变化吗?这个 Optional、Optional、Implicit Unwrapped Optional (?) 在这种情况下是什么意思,我如何声明这种类型的指针?

尝试

let myPointer = UnsafeMutablePointer<
    UnsafeMutablePointer<
    UnsafeMutablePointer<Int8>?>?>.allocate(capacity: 1)

或者,您也可以使用 _Nonnull 注释将指针保持为 non-optional。假设C函数是void setPtr(char ***)。您可以通过桥接 header 编写对 Swift 可用的声明,如下所示:

void setPtr(char * _Nonnull * _Nonnull * _Nonnull);

然后在你的 Swift 代码中你可以这样做:

let myPointer = UnsafeMutablePointer<
        UnsafeMutablePointer<
        UnsafeMutablePointer<Int8>>>.allocate(capacity: 1)
setPtr(myPointer)
let myInt = myPointer.pointee.pointee.pointee

但是如果 setPtr(char *** ptr) 在 C 代码中,其中 _Nonnull 不可用,会做类似

的事情怎么办?
*ptr = NULL;

?然后 Swift 代码将在运行时崩溃。但是,使用可选项,您不需要 setPtr() 声明中的 _Nonnull 注释,您的 Swift 代码变为

let myPointer = UnsafeMutablePointer<
        UnsafeMutablePointer<
        UnsafeMutablePointer<Int8>?>?>.allocate(capacity: 1)
setPtr(myPointer)
let myInt = myPointer.pointee?.pointee?.pointee

而且它不会在运行时崩溃。 因此,当您不使用 _Nonnull 时,由 Swift3 强制执行的可选方法更安全。