从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
相关产品推荐
相关产品推荐

