神刀安全网

每周 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 相关问题整理

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » 每周 Swift 社区问答:@convention

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址