Objective-c 代码的 Swift 3 闭包语法
Posted
技术标签:
【中文标题】Objective-c 代码的 Swift 3 闭包语法【英文标题】:Swift 3 closure syntax for objective-c code 【发布时间】:2016-09-23 17:40:57 【问题描述】:我正在使用一个公开以下 Objective-c 方法的库:
- (void)signIn:(NSString *)username password:(NSString *)password completion:(void (^)(User *user, NSError *error))completion;
我想像这样调用 swift 3 中的方法:
sign(in: "abc", password: "def") (user: User?, error: NSError?) -> Void in
// ...
编译器引发以下错误:
无法将类型 '(User?, NSError?) -> Void' 的值转换为预期的参数类型 '((User?, Error?) -> Void)!'
在这个例子中我遗漏了什么?
【问题讨论】:
【参考方案1】:当您在 Xcode 中查看库的标题时,点击“相关项目”弹出菜单(编辑器左上方的四个正方形图标)并选择“生成的界面”。这将向您展示您的 ObjC 代码的 Swift 接口是什么样的,包括该闭包参数的类型签名。
很可能类似于@escaping (user: User?, error: Error?) -> Void
。但这只是我的猜测——请务必阅读生成的界面。
注意:
导入的闭包假定为@escaping
。 (不过,当您创建要传递给您的函数的闭包时,您不必在使用站点上编写它。)
NSError
指针通常被转换为Error
协议引用。
参数类型是作为可选还是非可选导入取决于 ObjC 文件中的可空性(或 NS_ASSUME_NONNULL
)注释。
【讨论】:
感谢生成界面的提示。不幸的是,它仍然没有解决问题。这是输出:open func log(in username: String!, password: String!, completion: (@escaping (User?, Error?) -> Swift.Void)!)
【参考方案2】:
Xcode 的自动完成功能可以为您提供很多帮助。从弹出菜单中选择函数,按 Tab 以获取函数签名,再按几个 Tab 直到到达 completion
参数,然后按 Enter。这是 XCode 给我的:
instance.sign(in: String!, password: String!) (User?, Error?) in
// code
所以你的闭包语法应该是这样的:
instance.sign(in: String!, password: String!) user, error in
// code
【讨论】:
以上是关于Objective-c 代码的 Swift 3 闭包语法的主要内容,如果未能解决你的问题,请参考以下文章
Swift 3.0 令人兴奋,但Objective-C也有小改进--Objective-C的类属性
转换为 Swift 3 重命名了我自己的 Objective-C 方法