Swift不会将Objective-C NSError **转换为throws [英] Swift doesn't convert Objective-C NSError** to throws
问题描述
我有一些Objective-C遗留代码,声明方法如
I have some Objective-C legacy code, that declares method like
- (void)doSomethingWithArgument:(ArgType)argument error:(NSError **)error
Swift自动将产生错误
的Objective-C方法转换为根据以下方法抛出错误的方法Swift的原生错误
处理功能。
Swift automatically translates Objective-C methods that produce errors into methods that throw an error according to Swift’s native error handling functionality.
但在我的项目中描述的方法是这样调用的:
But in my project described methods are called like this:
object.doSomething(argument: ArgType, error: NSErrorPointer)
此外,当我尝试使用它们时会抛出运行时异常:
Moreover, it throws runtime exception when I try to use them like:
let errorPtr = NSErrorPointer()
object.doSomething(argumentValue, error: errorPtr)
我是否还需要更多东西来将Objective-CNSError **方法转换为Swifttrows方法?
Do I need something more to convert Objective-C "NSError **" methods to Swift "trows" methods?
推荐答案
只返回 BOOL
或(可为空)对象
的Objective-C方法转换为throw Swift中的方法。
Only Objective-C methods which return a BOOL
or a (nullable) object
are translated to throwing methods in Swift.
原因是Cocoa方法总是使用返回值 NO
或 nil
表示方法失败,而不只是设置错误对象。
这记录在
使用和创建错误对象:
The reason is that Cocoa methods always use a return value NO
or nil
to indicate the failure of a method, and not just set an error object.
This is documented in
Using and Creating Error Objects:
重要提示:返回表示成功或失败方法的价值。
虽然在Cocoa错误
域中间接返回错误对象的Cocoa方法保证返回此类对象,如果方法通过直接返回nil或NO指示失败
,则应始终检查返回在尝试对NSError对象执行任何操作之前,
值为nil或NO。
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接口
For example, the Objective-C interface
@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
已映射to Swift as
is mapped to 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
}
如果你可以改变方法的接口,那么你应该添加一个布尔值
返回值表示成功或失败。
If you can change the interface of your method then you should add a boolean return value to indicate success or failure.
否则你将从Swift中调用它
Otherwise you would call it from Swift as
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中抛出错误:
I found that Clang has an attribute which forces a function to throw an error in Swift:
-(void)doSomethingWithArgument5:(int) x error:(NSError **)error
__attribute__((swift_error(nonnull_error)));
映射到Swift为
public func doSomethingWithArgument5(x: Int32) throws
似乎工作正常如预期的那样。但是,我找不到关于此属性的任何官方文档
,所以依赖它可能不是一个好主意。
and seems to work "as expected". However, I could not find any official documentation about this attribute, so it might not be a good idea to rely on it.
这篇关于Swift不会将Objective-C NSError **转换为throws的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!