Hi,SwiftGG 翻译组启用了新的域名:swiftgg.team今后翻译组的各项活动将会在新域名下开展,不要错过哦!

今天我们来介绍一下@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 相关问题整理

文章目录
  1. 1. @convention解释
  2. 2. @convention使用举例
    1. 2.1. 在 Swift 中调用包含函数指针参数的 C 函数
    2. 2.2. 在 Swift 中调用包含 block 参数的 Objective-C 方法
  3. 3. stackoverflow 相关问题整理
  4. 4. 参考资料