Swift 2.0 和 objective-c 兼容方法 returns Bool with parameter NSError

Swift 2.0 and objective-c compatibility method returns Bool with parameter NSError

我正在开发一个使用 objective-c 框架的新项目,所有新代码都在 Swift 中。我遇到了一个有趣的兼容性问题。问题来自 Swift 2.0,其中 objective-c 中任何 return 是 BOOL 并采用 NSError 参数的方法都被转换为 returns VoidthrowsSwift。这种翻译的一个例子是 NSManagedObjectContext 保存方法,它现在位于 Swift:

public func save() throws

当从 Swift 调用代码并且实现也在 Swift 中时,这不是问题。

我面临的问题是我无法(或不应)在遵循相同模式的 objective-c 中修改的框架。在这种情况下,我正在实现在 objective-c 协议中定义的那个方法,当在 Swift 中实现它时,让编译器满意的唯一方法是 return Void 并抛出一些东西,当 objective-c 调用我的方法时,它会在内部捕获错误并且 return 值变为 NO,这是我想要的行为。

但是现在告诉我发生了什么的 NSError 是 nil,并且似乎无法从 Swift 设置它,因为它甚至没有传入参数,并且遵守协议的唯一方法是将其删除。我不仅在抛出的异常中看不到消息,而且现在我也看不到 NSError。我只知道调用失败但没有任何消息 log/display 失败原因,或者可能在某些失败条件下重试。

我一直在寻找一种方法 Objective-c 可以将 ErrorType 桥接到 NSError 但根本找不到任何东西。就像它在内部捕获 ErrorType 并将 return 值设置为 NO.

一样

有什么方法可以解决这个问题,无需更改 objective-c 协议定义?

给定协议定义

@protocol MyProtocol <NSObject>
- (BOOL)myMethod:(NSInteger)x error:(NSError *__autoreleasing *)error;
@end

您可以在 Swift 中实现符合要求的 class 并抛出 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.