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

从Objective-C调用Swift async异步函数报错找不到方法如何解决

问题原因

Swift 5.5引入的async/await异步模型是Swift专属的运行时特性,Objective-C没有对应的原生语法和调用约定,因此直接标记@objc的async Swift方法不会被添加到生成的Swift-ObjC桥接头文件中,这就是你找不到selector的核心原因。

解决方案

方案1:手动添加Objective-C兼容的闭包回调桥接层(兼容所有Swift 5.5+版本)

你可以在Swift类中额外声明一个带完成回调的@objc方法,内部调用你的async异步方法,适配ObjC的调用习惯:

@MainActor
func updateStatus() async {
    /// do async stuff...
}

// 新增给ObjC调用的桥接方法
@objc @MainActor func updateStatusWithCompletion(completion: @escaping () -> Void) {
    Task {
        await updateStatus()
        completion()
    }
}

// 如果async方法有返回值/抛出错误,可以调整回调参数适配
@objc @MainActor func fetchStatusWithCompletion(completion: @escaping (NSString?, NSError?) -> Void) {
    Task {
        do {
            let status = try await fetchStatus()
            completion(status as NSString, nil)
        } catch {
            completion(nil, error as NSError)
        }
    }
}

修改完成后在Objective-C中直接调用桥接方法即可:

if (@available(iOS 15.0, *)) {
     CJSubscriptionStatusCheck *backgroundStatusCheck = [[CJSubscriptionStatusCheck alloc] init];
     [backgroundStatusCheck updateStatusWithCompletion:^{
         // 异步任务完成后的逻辑
     }];
}

方案2:使用Swift自动ObjC桥接(需Swift 5.7+版本)

从Swift 5.7开始,编译器支持自动将Swift async函数桥接为Objective-C的completion handler风格方法,你只需满足两个条件:

  • 项目Swift语言版本设置为5.7及以上
  • 函数的返回值、参数都为ObjC兼容类型
    此时你只需要给async方法添加@objc的同时指定暴露给ObjC的selector名即可:
@MainActor
@objc(updateStatusWithCompletion:)
func updateStatus() async {
    /// do async stuff...
}

编译器会自动生成对应的ObjC方法声明,调用方式和手动写的桥接方法完全一致。

注意事项

  • 两种方案都要求运行环境为iOS 15.0及以上版本,你代码中的@available判断是必须保留的
  • 如果async方法会抛出错误,自动桥接后的ObjC方法会自动把error作为回调的最后一个参数,不需要额外手动处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 06:06:07