Swift不会将Objective-C NSError**转换为throws

Ant*_*tin 22 objective-c nserror ios swift

我有一些Objective-C遗留代码,它声明了类似的方法

- (void)doSomethingWithArgument:(ArgType)argument error:(NSError **)error
Run Code Online (Sandbox Code Playgroud)

正如这里所写的https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html

Swift会自动将产生错误的Objective-C方法转换为根据Swift的本机错误处理功能引发错误的方法.

但在我的项目中描述的方法如下所示:

object.doSomething(argument: ArgType, error: NSErrorPointer)
Run Code Online (Sandbox Code Playgroud)

此外,当我尝试使用它们时,它会抛出运行时异常:

let errorPtr = NSErrorPointer()
object.doSomething(argumentValue, error: errorPtr)
Run Code Online (Sandbox Code Playgroud)

我还需要更多东西来将Objective-C"NSError**"方法转换为Swift"trows"方法吗?

Mar*_*n R 36

只返回一个BOOL或一个(可空)对象的Objective-C方法被转换为Swift中的抛出方法.

其原因是,Cocoa方法总是用一个返回值NOnil 指示的方法的失败,而不是只设置一个错误对象.这在 使用和创建错误对象中有记录:

重要说明:方法的返回值表示成功或失败.虽然在Cocoa错误域中间接返回错误对象的Cocoa方法可以保证返回这样的对象,如果方法通过直接返回nil或NO来指示失败,你应该在尝试对之做任何事情之前检查返回值为nil或NO. NSError对象.

例如,Objective-C接口

@interface OClass : NSObject

NS_ASSUME_NONNULL_BEGIN

-(void)doSomethingWithArgument1:(int) x error:(NSError **)error;
-(BOOL)doSomethingWithArgument2:(int) x error:(NSError **)error;
-(NSString *)doSomethingWithArgument3:(int) x error:(NSError **)error;
-(NSString * _Nullable)doSomethingWithArgument4:(int) x error:(NSError **)error;

NS_ASSUME_NONNULL_END

@end
Run Code Online (Sandbox Code Playgroud)

映射到Swift as

public class OClass : NSObject {

    public func doSomethingWithArgument1(x: Int32, error: NSErrorPointer)
    public func doSomethingWithArgument2(x: Int32) throws
    public func doSomethingWithArgument3(x: Int32, error: NSErrorPointer) -> String
    public func doSomethingWithArgument4(x: Int32) throws -> String
}
Run Code Online (Sandbox Code Playgroud)

如果您可以更改方法的接口,则应添加布尔返回值以指示成功或失败.

否则你会从Swift中调用它

var error : NSError?
object.doSomethingWithArgument(argumentValue, error: &error)
if let theError = error {
    print(theError)
}
Run Code Online (Sandbox Code Playgroud)

备注:

我发现Clang有一个强制函数在Swift中抛出错误的属性:

-(void)doSomethingWithArgument5:(int) x error:(NSError **)error
  __attribute__((swift_error(nonnull_error)));
Run Code Online (Sandbox Code Playgroud)

映射到Swift as

public func doSomethingWithArgument5(x: Int32) throws
Run Code Online (Sandbox Code Playgroud)

并且似乎"按预期工作".但是,我找不到任何关于此属性的官方文档,因此依赖它可能不是一个好主意.

  • 很好找!我在这里找到了属性的文档:https://github.com/apple/swift-clang/blob/383859a9c4b964af3d127b5cc8abd0a8f11dd164/include/clang/Basic/AttrDocs.td#L1800-L1819 (3认同)