Swift 2.0和objective-c兼容性方法返回Bool参数NSError

时间:2016-02-23 17:09:53

标签: objective-c swift error-handling compatibility nserror

我正在开发一个使用objective-c框架的新项目,所有新代码都在Swift中。我遇到了兼容性方面的一个有趣问题。问题来自Swift 2.0,其中objective-c中返回BOOL并采用NSError参数的任何方法都会转换为返回Voidthrows的方法在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协议定义?

1 个答案:

答案 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中。