Swift3更改为UnsafeMutablePointer

时间:2016-09-26 10:03:41

标签: swift3 xcode8 unsafemutablepointer

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

的函数参数
char ***

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

UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<Int8>>>

所以我可以在我的快速代码中声明指针:

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中的变化吗?这个可选,可选,隐式解包可选(?)在这个上下文中意味着什么?我如何声明这种类型的指针?

1 个答案:

答案 0 :(得分:0)

尝试

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

或者,您也可以使用_Nonnull注释将指针保持为非可选。假设C函数是void setPtr(char ***)。您可以通过桥接标题将其声明写入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)_Nonnull不可用的情况下*ptr = NULL; 会发生什么呢?

_Nonnull

?然后Swift代码将在运行时崩溃。但是,在setPtr()声明中使用您不需要let myPointer = UnsafeMutablePointer< UnsafeMutablePointer< UnsafeMutablePointer<Int8>?>?>.allocate(capacity: 1) setPtr(myPointer) let myInt = myPointer.pointee?.pointee?.pointee 注释的选项,您的Swift代码就会变为

_Nonnull

它在运行时不会崩溃。 因此,当您不使用from itertools import accumulate # Or copy accumulate equivalent Python code from itertools import chain # Calls could be inlined in listcomp, but easier to read here starts = accumulate(chain((0,), v)) # Extra value from starts ignored when ends exhausted ends = accumulate(v) list1,list2,list3,list4 = [l[s:e] for s, e in zip(starts, ends)] 时,由Swift3强制执行的选项的方法更安全。