Подтвердить что ты не робот

New @convention (c) в Swift 2: Как я могу использовать его?

После миграции на Swift 2 я получаю эту проблему с ошибкой, заявляя, что теперь я должен использовать @convention (c) (T) → U. Я пробовал перестановки, но пока не повезло.

func foo(context: AnyObject?, width: CGFloat) -> Int {

}

let bar = unsafeBitCast(foo, CFunctionPointer<(UnsafeMutablePointer<Void>, Float) -> Int>.self)
4b9b3361

Ответ 1

Вам больше не нужно создавать CFunctionPointer в Swift 2. Вместо этого вы можете аннотировать свой тип, вызывая соглашение, в данном случае c, и использовать его напрямую.

typealias CFunction = @convention(c) (UnsafeMutablePointer<Void>, Float) -> Int
let bar = unsafeBitCast(foo, CFunction.self)

Соответствующие биты описания @convention в разделе "Атрибуты типов" "Язык быстрого программирования":

Аргумент c используется для указания ссылки на функцию C. Значение функции не имеет контекста и использует соглашение C-вызова.

Ответ 2

Передача Swift замыкания на C-функцию с помощью указателя функции параметр теперь поддерживается в Swift 2, и, как вы заметили, функция типы указываются с атрибутом @convention(c).

Если вы передаете закрытие непосредственно в качестве аргумента функции C, тогда этот атрибут выводится автоматически.

В качестве простого примера, если у вас есть эта функция C

CGFloat myCFunction(CGFloat (callback)(CGFloat x, CGFloat y)) {
    return callback(1.1, 2.2);
}

то вы можете вызвать его из Swift как

let result = myCFunction( {
    (x, y) -> CGFloat in
    return x + y
} )
print(result) // 3.3

который делает то же самое, что и более подробный

let swiftCallback : @convention(c) (CGFloat, CGFloat) -> CGFloat = {
    (x, y) -> CGFloat in
    return x + y
} 

let result = myCFunction( swiftCallback )
print(result) // 3.3