【问题标题】:Typedef Return-Type in Objective-C does not work in SwiftObjective-C 中的 Typedef Return-Type 在 Swift 中不起作用
【发布时间】:2017-01-05 22:55:49
【问题描述】:

我想在我的 Swift 项目中使用 Objective-C 类并导入文件,Xcode 创建了桥头文件,一切都很酷......除了:

Objective-C 类为函数定义了回调类型

typedef void (^SSScanManagerCallback)(BOOL success, NSError *error, NSArray *scannedURLs);

并使用函数声明中的类型

- (void)scanSync:(SSScanManagerCallback)callback; // Synchronous scan.

有问题的类如下:https://github.com/counsyl/scanstream/blob/master/ScanStream/SSScanManager.h#L16

如果我想在 Swift 中使用该类:

let scanManager = SSScanManager();
scanManager.scanSync({(_ success: Bool, _ error: Error, _ scannedURLs: [Any]) -> Void in
    if !success {
        // ...
    }
});

我收到以下错误:

无法将类型 '(Bool, Error, [Any]) -> Void' 的值转换为预期的参数类型 'SSScanManagerCallback!'


更新:即使我尝试像这样设置参数类型:

scanManager.scanSync({(_ justATry: SSScanManagerCallback!) -> Void in

});

我得到错误:

无法将类型“(SSScanManagerCallback!)-> Void”的值转换为预期的参数类型“SSScanManagerCallback!”

但是我如何将类型设置为“SSScanManagerCallback!”按照错误消息中的要求?

【问题讨论】:

  • 只需删除显式类型注释——让 Swift 推断它们(即.scanSync {success, error, scannedURLs in ... }。参见例如Using Obj-C completion block in Swift
  • @Hamish 太棒了,效果很好,谢谢!很想给你正确的答案复选标记;-)
  • 请注意,在 Swift 中,您不需要在每条语句的末尾写分号——我还建议您看看可以编写闭包的各种速记方法 ( developer.apple.com/library/content/documentation/Swift/…)
  • 感谢您的提示!最后我有点喜欢分号,但我可以理解人们很高兴能够摆脱它们。

标签: objective-c swift callback typedef


【解决方案1】:

有趣的是,看起来 Swift(在 3.0.2 中测试)现在将没有任何可空性注释的 Objective-C 块参数类型作为强选项导入(以前它们被导入为隐式展开的选项)。不过,我似乎找不到有关此更改的文档。

所以在你的情况下,正确的签名是:

scanManager.scanSync {(success: Bool, error: Error?, scannedURLs: [Any]?) -> Void in
    // ...
}

但是永远不要这样写,总是让 Swift 尽可能地推断参数类型,它为你解决了这些类型不匹配的问题。

scanManager.scanSync { success, error, scannedURLs in
    // ...
}

现在你可以点击闭包参数,Xcode会告诉你Swift推断它们的类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    • 1970-01-01
    • 2015-10-23
    • 1970-01-01
    • 2022-09-28
    • 1970-01-01
    相关资源
    最近更新 更多