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

如何在无回调同步方法中调用Swift异步方法?适配OC框架

同步OC代理适配Swift Async代理的解决方案及可行性分析

适配器方案可行性结论

代理适配器方案完全可行,核心是通过手动实现「异步转同步」的逻辑,打通OC同步代理与Swift异步代理的调用链路,同时规避并发模型差异带来的编译错误与运行时问题。


核心解决思路

OC的同步代理方法需要阻塞等待Swift async方法的执行结果,这里用GCD信号量(Semaphore)实现同步阻塞,搭配后台队列调度异步任务,避免主线程死锁。

代码实现示例

1. OC端代理适配器类

这个类作为OC框架代理的实现者,同时持有Swift异步代理的引用,负责中转调用:

// OCProxyAdapter.h
#import <Foundation/Foundation.h>
@protocol OCFrameworkDelegate;
@protocol SwiftAsyncProxy;

@interface OCProxyAdapter : NSObject <OCFrameworkDelegate>
@property (nonatomic, weak) id<SwiftAsyncProxy> swiftProxy;
@end

// OCProxyAdapter.m
#import "OCProxyAdapter.h"
#import "YourSwiftBridgeHeader.h" // 替换为你的Swift桥接头文件

@implementation OCProxyAdapter

- (NSString *)frameworkRequestDataWithParam:(NSString *)param {
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    __block NSString *result = @"";
    
    // 切换到后台队列执行异步调用,避免主线程死锁
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 用Task包裹Swift异步方法调用
        Task {
            result = await self.swiftProxy?.requestData(param: param) ?? @"";
            // 异步任务完成后发送信号量,唤醒阻塞的主线程
            dispatch_semaphore_signal(semaphore);
        }
    });
    
    // 阻塞当前线程,等待异步任务结果
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    return result;
}

@end

2. Swift端异步代理协议与实现

保持Swift原生的async/await写法,符合需求要求:

// SwiftAsyncProxy.swift
@objc protocol SwiftAsyncProxy {
    func requestData(param: String) async -> String
}

// 示例实现类,业务逻辑写在这里
class MySwiftProxy: NSObject, SwiftAsyncProxy {
    func requestData(param: String) async -> String {
        // 模拟异步操作(比如网络请求、本地IO)
        await Task.sleep(nanoseconds: 1_000_000_000)
        return "Processed result for: \(param)"
    }
}

3. 绑定适配器与代理

在Swift代码中完成适配器、Swift代理与OC框架的关联:

let framework = OCFramework.shared // 你的OC框架实例
let adapter = OCProxyAdapter()
let swiftProxy = MySwiftProxy()

adapter.swiftProxy = swiftProxy
framework.delegate = adapter

关键注意事项

  • 规避主线程死锁:如果OC框架的代理方法是在主线程调用的,必须把Swift异步方法的调度放到后台队列,否则会导致主线程阻塞死锁。
  • 错误处理:如果Swift async方法可能抛出错误,需要在Task中用do-catch捕获,设置合理的错误返回值,避免程序崩溃。
  • 避免循环引用:OC适配器中对Swift代理使用weak引用,防止出现循环引用导致内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 06:45:14