我正在开发一个使用objective-c框架的新项目,所有新代码都在Swift
中。我遇到了兼容性方面的一个有趣问题。问题来自Swift 2.0,其中objective-c
中返回BOOL
并采用NSError
参数的任何方法都会转换为返回Void
和throws
的方法在Swift
。这种翻译的一个例子是NSManagedObjectContext
保存方法,现在在Swift中:
public func save() throws
当从Swift调用代码并且实现也在Swift中时,这不是问题。
我面临的问题是框架,我不能(或不应该)在objective-c中修改遵循相同模式的框架。在这种情况下,我正在实现在objective-c
协议中定义的方法,当在Swift
中实现它时,使编译器满意的唯一方法是返回Void并抛出一些东西,当{{ 1}}调用我的方法,它在内部捕获错误,返回值变为objective-c
,这是我想要的行为。
然而现在NO
告诉我发生了什么是nil,并且似乎没有办法从Swift设置它,因为它甚至没有在参数中传递,并且唯一的方法是遵守协议是把它拿出来的。我不仅没有在抛出的异常中看到消息,而且现在我看不到NSError
。我只知道调用失败但没有任何消息来记录/显示失败的原因,或者在某些失败条件下重试。
我一直在寻找一种方法,Objective-c可以将NSError
桥接到ErrorType
,但根本找不到任何东西。就像它在内部捕获NSError
一样,并将返回值设置为NO。
有没有办法可以解决这个问题而不改变objective-c协议定义?
答案 0 :(得分:3)
给定协议定义
@protocol MyProtocol <NSObject>
- (BOOL)myMethod:(NSInteger)x error:(NSError *__autoreleasing *)error;
@end
你可以在Swift中实现一个符合要求的类并抛出一个NSError
:
class SwClass : NSObject, MyProtocol {
func myMethod(x: Int) throws {
if x < 0 {
throw NSError(domain: "my.domain", code: 1234, userInfo: ["error" : "called with negative argument"])
}
}
}
从Objective-C调用时,错误被分配给传递的
NSError
变量:
-(void)foo {
SwClass *obj = [[SwClass alloc] init];
NSError *error;
if (![obj myMethod:-3 error:&error]) {
NSLog(@"%@", error);
}
}
因此,协议方法是否实施无关紧要 在Objective-C或Swift中。