【问题标题】:Swift 3 closure syntax for objective-c codeObjective-c 代码的 Swift 3 闭包语法
【发布时间】: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)!'

在这个例子中我遗漏了什么?

【问题讨论】:

    标签: swift closures swift3


    【解决方案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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-17
      • 2017-09-29
      • 1970-01-01
      • 1970-01-01
      • 2015-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多