在Swift中调用抛出异常的objc代码



我在ObjC/C中有这个代码:

AVCaptureFocusMode GetFocusModeWithString(NSString *mode) {
if ([mode isEqualToString:@"locked"]) {
return AVCaptureFocusModeLocked; 
} else if ([mode isEqualToString:@"auto"]) {
return AVCaptureFocusModeAutoFocus;
} else {
@throw [NSError errorWithDomain: @"FocusError", code: 12];
}
}

当从ObjC代码调用时,它曾经工作得很好。现在我用swift重写调用方。然而,在swift中,这段代码实际上不会抛出:

// does not work, swift thinks this function does not throw. 
do {
try GetFocusModeWithString(@"auto")
}

我做错了什么吗?ObjC代码不好吗?我怎样才能改善ObjC代码与swift很好地工作?

Objective C没有像Swift那样的do/try/catch语义。

@throw导致运行时异常。这不是你可以在Swift中捕捉到的。

将Cocoa错误处理与Swift集成的方法在Swift Objective C互操作性文档中有描述,这个答案

首先声明你的Objective-C函数接受一个指向NSError实例的指针。然后您可以使用__attribute__((swift_error(nonnull_error)))标记该参数的函数。

当函数返回

时,如果错误非空,将导致Swift异常。
- (AVCaptureFocusMode) getFocusModeWithString:(NSString *) mode error: (NSError **)error __attribute__((swift_error(nonnull_error))); {
*error = nil;
if ([mode isEqualToString:@"locked"]) {
return AVCaptureFocusModeLocked;
} else if ([mode isEqualToString:@"auto"]) {
return AVCaptureFocusModeAutoFocus;
}
*error = [NSError errorWithDomain:@"FocusError" code:12 userInfo:nil];
return -1;
}
现在,在你的Swift代码中你可以用 来调用它
do {
let focusMode = try getFocusMode(with: "auto")
} catch {
print(error)
}

注意这将改变你在Objective-C中的方法签名;您需要将&error传递给该方法,并在返回时检查其值。

Objective-C异常与Swift不兼容。苹果公司是这么说的:

在Objective-C中处理异常

在Objective-C中,异常不同于错误。Objective-C异常处理使用@try,@catch@throw语法来指示不可恢复的程序员错误。这与上面描述的Cocoa模式不同,后者使用后面的NSError参数来指示您在开发期间计划的可恢复错误。

在Swift中,你可以从使用Cocoa的错误模式传递的错误中恢复,如上面的Catch errors中所述。然而,在Swift中没有从Objective-C异常中恢复的安全方法。要处理Objective-C异常,编写在异常到达任何Swift代码之前捕获异常的Objective-C代码。

相关内容

  • 没有找到相关文章

最新更新