问题描述
我有一些Objective-C遗留代码,声明方法如
I have some Objective-C legacy code, that declares method like
- (void)doSomethingWithArgument:(ArgType)argument error:(NSError **)error
如此处所写
但在我的项目中描述的方法是这样调用的:
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) objectare 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 inUsing and Creating Error Objects:
例如,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 booleanreturn 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 documentationabout this attribute, so it might not be a good idea to rely on it.
这篇关于Swift不会将Objective-C NSError **转换为throws的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!