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

我有一些Objective-C遗留代码,它声明方法
- (void)doSomethingWithArgument:(ArgType)argument error:(NSError **)error

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

Swift automatically translates Objective-C methods that produce errors
into methods that throw an error according to Swift’s native error
handling functionality.

但是在我的项目中描述的方法叫做:

object.doSomething(argument: ArgType,error: NSErrorPointer)

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

let errorPtr = NSErrorPointer()
object.doSomething(argumentValue,error: errorPtr)

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

解决方法

只有返回BOOL或(可空)对象的Objective-C方法
被翻译成在Swift中投掷方法.

原因是Cocoa方法总是使用返回值NO或nil
以指示方法的失败,而不仅仅是设置错误对象.
这被记录在
Using and Creating Error Objects

Important: Success or failure is indicated by the return value of the method.
Although Cocoa methods that indirectly return error objects in the Cocoa error
domain are guaranteed to return such objects if the method indicates failure
by directly returning nil or NO,you should always check that the return
value is nil or NO before attempting to do anything with the NSError object.

例如,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

被映射到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
}

如果您可以更改方法的界面,那么您应该添加一个布尔值
返回值表示成功或失败.

否则你会把它从Swift称为

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

备注:

> https://github.com/apple/swift/blob/master/test/Inputs/clang-importer-sdk/usr/include/errors.h

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

-(void)doSomethingWithArgument5:(int) x error:(NSError **)error
  __attribute__((swift_error(nonnull_error)));

被映射到Swift as

public func doSomethingWithArgument5(x: Int32) throws

似乎按预期工作.但是,我找不到任何官方文件关于这个属性,所以可能不是一个好主意依靠它.

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...