You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift调用OC含NSError方法的两个问题:异常捕获与返回值缺失

问题背景

我定义了如下Objective-C类:

@interface TestModel : NSObject

- (BOOL)test1:(NSError * _Nullable * _Nullable)error;

- (int)test2:(NSError * _Nullable * _Nullable)error;

@end
    
@implementation TestModel

- (BOOL)test1:(NSError * _Nullable * _Nullable)error {
    return YES;
}

- (int)test2:(NSError * _Nullable * _Nullable)error {
    if (error) {
        *error = [NSError errorWithDomain:@"domain" code:0 userInfo:nil];        
    }
    return 9;
}

@end

随后我在Swift中这样调用:

@objcMembers
@objc public class Utils: NSObject {
    func test() {
        do {
            let value = try TestModel().test1()
            print("success value: \(value)")
        } catch  {
            print("failed error: \(error)")
        }
        
        var error: NSError?
        let value = TestModel().test2(&error)
        print("value>>>>>> \(value)")
    }
}

运行后得到结果:

success value: ()
value>>>>>> 9

我有两个技术疑问:

  1. 为什么调用test1时需要通过try-catch捕获异常,而调用test2时却不需要?
  2. 为什么调用test1后没有获取到预期的返回值?
解答

问题1:test1需要try-catch,test2不需要的原因

这是Swift对Objective-C错误处理的桥接规则导致的:

  • 当Objective-C方法返回值为BOOL,且最后一个参数是NSError **时,Swift会自动将其桥接成**抛出错误(throws)**的方法。因为Objective-C的通用约定是:BOOL返回NO代表操作失败,同时通过NSError **输出错误信息,Swift直接把这种模式映射成自身的throws错误处理机制,所以调用时必须用try配合do-catch、try?或try!。
  • 而test2的返回值是int类型,不符合Swift自动桥接成throws方法的规则。Swift会保留Objective-C原有的错误传递方式,也就是通过传入NSError?指针获取错误,因此不需要try-catch。

问题2:test1没有返回预期值的原因

还是源于Swift与Objective-C的桥接规则:
当Objective-C的BOOL返回值+NSError **参数的方法被桥接成Swift的throws方法时,原有的BOOL返回值会被忽略——Swift的throws方法约定:只要方法不抛出错误,就代表操作成功,原来的YES/NO已经被映射为“是否抛出错误”的逻辑。因此你在Swift中调用try test1()时,得到的返回值是Void(即代码中的()),而非原Objective-C方法返回的YES。

如果想在Swift中获取test1的BOOL返回值,需要修改Objective-C的方法签名,打破自动桥接成throws的规则,比如给方法添加NS_SWIFT_NOTHROW宏:

- (BOOL)test1:(NSError * _Nullable * _Nullable)error NS_SWIFT_NOTHROW;

这样Swift会将其视为普通方法,你可以像调用test2那样传入错误指针,同时获取Bool类型的返回值。

内容的提问来源于stack exchange,提问作者x_z

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 09:15:32