3

我是 Swift 新手,我开始探索一些与 Objective-C 桥接的功能。

目前我有一个NSError参考方法是:

- (BOOL) verifyPersonalizationWithError:(NSError **) error NS_REFINED_FOR_SWIFT;

现在我可以访问 Swift 中的方法进行一些改进,但返回值丢失了。Swift 的生成方法是:

open func __verifyPersonalization() throws

使用 do catch 可以正确处理该错误,但返回值似乎丢失了。

我的 NS_REFINED_FOR_SWIFT 宏有什么遗漏吗?

4

1 回答 1

16

这与NS_REFINED_FOR_SWIFT宏无关。Objective-C 方法

 - (BOOL) verifyPersonalizationWithError:(NSError **) error;

被导入到 Swift 作为

open func verifyPersonalization() throws

宏的唯一作用NS_REFINED_FOR_SWIFT是在 Swift 方法名称前加上下划线

open func __verifyPersonalization() throws

它允许在扩展中提供精炼的 Swift 接口,同时保持可从精炼的接口调用的原始实现(请参阅同一项目中的 Swift 和 Objective-C 中的“精炼 Objective-C 声明” )。

Swift 导入器假定 Objective-C 方法的布尔返回值指示成功或失败,这是使用和创建错误对象中记录的常见 Cocoa 模式:

重要提示:成功或失败由方法的返回值指示。虽然间接返回 Cocoa 错误域中的错误对象的 Cocoa 方法如果通过直接返回 nil 或 NO 指示失败,则保证返回此类对象,但在尝试对NSError 对象。

Objective-C 中的一个典型用法是

NSError *error;
if ([self verifyPersonalizationWithError:&error]) {
    NSLog(@"success");
} else {
    NSLog(@"failed: %@", error.localizedDescription);
}

Swift 方法在失败时会抛出错误,因此不需要布尔返回值:

do {
    try verifyPersonalization()
    print("success")
} catch {
    print("failed:", error.localizedDescription)
}

如果 Objective-C 方法确实通过在错误参数中留下非空错误来指示失败(而不是返回false,这是通常的 Cocoa 模式),那么您可以通过添加属性来指示:

- (BOOL) verifyPersonalizationWithError:(NSError **) error
    __attribute__((swift_error(nonnull_error)));

导入到 Swift 作为

open func verifyPersonalization() throws -> Bool

swift_error属性记录在https://github.com/apple/swift-clang/blob/383859a9c4b964af3d127b5cc8abd0a8f11dd164/include/clang/Basic/AttrDocs.td#L1800-L1819

于 2017-08-08T10:47:35.273 回答