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

Swift调用Objective-C返回BOOL的方法时返回值被推断为()而非Bool

问题原因

该报错由Swift对Objective-C方法的默认桥接规则导致:

  • 按照Cocoa通用约定,返回BOOL且最后一个参数为NSError **类型的Objective-C方法,Swift会默认将其转换为throws类型的无返回值方法:原方法返回YES时Swift判定执行成功,不抛出错误;原方法返回NO时Swift自动将errorPtr指向的NSError对象抛出,原BOOL返回值会被直接丢弃。因此你调用方法得到的ret类型为Void(也就是()),无法作为Bool类型用于条件判断。
  • 你提到的返回值在dispatch_sync内部赋值是方法的实现逻辑,和本次报错没有关联。
解决方案

根据你是否可以修改原Objective-C方法代码,有两种可选方案:

方案1:可修改原OC方法代码

在方法声明末尾添加NS_SWIFT_NOTHROW注解,主动告知Swift不要将该方法转换为throws方法,保留原BOOL返回值:

- (BOOL)methodName:(NSDictionary<NSString *, NSString *> *)params callback:(void(^)(NSString *_Nullable, ErrorInformation *_Nullable))callback error:(NSError *_Nullable *_Nullable)errorPtr NS_SWIFT_NOTHROW;

修改后Swift中调用该方法的返回值为Bool类型,error参数变为UnsafeMutablePointer<NSError?>?类型,可自行处理error指针,也能正常判断返回值:

var error: NSError?
let ret = methodName(params, callback: { result, infoError in
    // 处理回调逻辑
}, error: &error)
if ret {
    // 原返回值为YES的逻辑
}

方案2:无法修改原OC方法代码

如果不需要额外判断BOOL返回值,可以直接使用默认的do/try/catch逻辑:原方法返回YES时try语句不会抛出错误,直接执行do块内的逻辑即可,不需要额外接收返回值判断:

do {
    try methodName(params, callback: { result, infoError in
        // 处理回调逻辑
    })
    // 走到此处等价于原OC方法返回YES,直接写原if(ret)内的逻辑即可
} catch {
    // 原方法返回NO的逻辑,error为原errorPtr指向的NSError对象
}

如果既不能修改OC代码又要拿到BOOL返回值,可以在Objective-C层新增一个分类方法,包装原方法并添加NS_SWIFT_NOTHROW注解,再在Swift中调用新的包装方法即可。

注意:上述示例中调用方法时需要传入完整的params和callback参数,你提供的示例中methodName()仅为简写。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:30:02