转载

每周 Swift 社区问答:@convention

今天我们来介绍一下 @convention 特性关键字。

@convention 解释

@convention 特性是在 Swift 2.0 中引入的,用于修饰函数类型,它指出了函数调用的约定。用在以下几个地方:

  • 修饰 Swift 中的函数类型,调用 C 的函数时候,可以传入修饰过 @convention(c) 的函数类型,匹配 C 函数参数中的函数指针。
  • 修饰 Swift 中的函数类型,调用 Objective-C 的方法时候,可以传入修饰过 @convention(block) 的函数类型,匹配 Objective-C 方法参数中的 block 参数。

@convention 使用举例

在 Swift 中调用包含函数指针参数的 C 函数

我们定义了如下 C 函数:

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

其中 callback 是一个函数指针,需要调用者自己实现,在 Swift 中,如果需要实现 callback ,供 myCFunction 调用的话,有以下写法,这里就会用到 @convention :

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

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

另外,还有更加简单地直接使用闭包的做法,这里没有用到 @convention :

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

在 Swift 中调用包含 block 参数的 Objective-C 方法

与调用 C 的函数指针类似,要在 Swift 中调用一个含有 block 的 Objective-C 的方法时,需要使用 @convention(block) 定义 Swift 变量才能传入到 Objective-C 的方法中。当然也可以直接使用闭包,这里我们举一个动画方法的例子:

[UIView animateWithDuration:2 animations:^{
NSLog(@"start");
} completion:^(BOOL finished){
NSLog(@"completion");
}];

以上代码使用了 2 个 block,直接使用闭包转换成 Swift 代码:

UIView.animateWithDuration(2, animations: {
NSLog("start")
}, completion: {
(Bool completion) in
NSLog("completion")
})

等价使用 @convention(block) 的代码如下:

let animationsBlock : @convention(block) () -> () = {
NSLog("start")
}
let completionBlock : @convention(block) (Bool) -> () = {
(Bool completion) in
NSLog("start")
}

UIView.animateWithDuration(2, animations: animationsBlock, completion: completionBlock)

stackoverflow 相关问题整理

  • New @convention(c) in Swift 2: How can I use it?
    如何在 Swift 2 中,使用 @convention(c) ?
  • Re: Populating a Swift array in a C function callback
    还是关于如何调用 C 函数回调的问题,最后有苹果员工的作答。
  • Swift blocks not working
    Swift 中调用 OC block的问题。

    参考资料

  • 在 Swift 2.0 当中使用 C 语言回调 :翻译组翻译好文,我也参与了校对。这篇文章重点是讲 Swift 如何处理调用 C 语言中的函数回调。

  • COPAQUEPOINTER 和 C CONVENTION :喵神的 tips,其中部分讲到了 C 语言函数指针的问题。非常通俗易懂。

原文  http://swift.gg/2016/05/18/swift-qa-2016-05-18/
正文到此结束
Loading...