将NSError函数快速桥接到无法运行的throwable函数

时间:2015-11-20 01:50:27

标签: objective-c xcode swift

我在具有此签名的Obj-c文件中使用init函数(来自AWS SDK):

- (instancetype)initWithDictionary:(NSDictionary *)dictionaryValue error:(NSError **)error;

与此签名模板的桥接:

enter image description here

请注意,它仍然建议error类型为()的参数,这当然没有意义。为什么不能正确删除swift签名中的error和/或为什么error参数()?帮助者正确地说出throws

enter image description here

修改 事实证明问题是由超类弃用旧签名引起的:

- (instancetype)initWithDictionary:(NSDictionary *)dictionaryValue __attribute__((deprecated("Replaced by -initWithDictionary:error:")));

如果我评论说弃用它可以正常工作,看起来这可能是Swift对Obj-c的桥接中的一个错误

1 个答案:

答案 0 :(得分:1)

不是一个错误,但无可否认是一个奇怪的事。

在Swift中,根据它是throws是否过载了一个函数是不合法的:

func foo() {}
func foo() throws {} // invalid redeclaration of `foo`

带有最终NSError输出参数的ObjC方法在Swift中转换为throws方法。因此,如果您有两个仅在添加错误参数方面不同的ObjC方法,则无法使用Swift错误语法导入。

相反,NSError参数变为throws,但其参数标签仍保留为Void(又名())参数以保留方法签名独特之处。你这样称呼它:

// signature
func foo(thing: String, error: ()) throws
// call site
try foo("bar", error: ()) // enclose in do/catch as desired, or use `try!`

理论上,弃用应该导致ObjC方法的非错误版本在Swift中不可见(因此允许使用Swift错误语法导入错误版本)。也许这仅适用于您从AvailabilityMacros.h宏获得的某些特定弃用属性? (这可能值得filing a bug。)

确保不会导入非错误的ObjC方法的另一种方法是使用NS_SWIFT_UNAVAILABLE标记它。