2016-09-26 4 views
0

Я портирую одну из моих приложений iOS на Swift3/Xcode8. я встроил библиотеку C, которая ожидает параметр функции типа:Swift3 переходит на UnsafeMutablePointer

char *** 

В Swift2.3 это было переведено в:

UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<Int8>>> 

Так я мог бы заявить, что указатель в моем быстром коде как то:

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

Это работало хорошо, пока я не обновлен до Xcode8 с Swift3, теперь я получаю ошибку компиляции:

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

Могу ли я кому-нибудь помочь мне разобраться в изменениях в swift3? Что означает этот Необязательный, Необязательный, Неявный Unwrapped Необязательный (?) Означает в этом контексте и как я могу объявить указатель с этим типом?

+0

Но я не получил какие-либо ошибки '' 'пусть _ = UnsafeMutablePointer >> выделить. (Емкость: 1)' '' –

+0

@AlvinVarghese Я получаю ошибку, когда я передать его как пары к моей функции C, которая ожидает 'char ***' типа – Stitch

ответ

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) в коде C, где _Nonnull не подходит, делает что-то наподобие

*ptr = NULL; 

? Затем код Swift будет сбой во время выполнения. Однако использование опций не нужен _Nonnull аннотацию в декларации setPtr(), ваш Swift код становится

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

и он не будет врезаться во время выполнения. Таким образом, подход с опциями, установленный Swift3, когда вы не используете _Nonnull, безопаснее.

+0

Большое спасибо – Stitch

Смежные вопросы