如何将Swift异步API转为同步?兼容ObjC测试第三方v2框架
临时适配方案(仅用于测试验证)
针对Swift和ObjC端的接口适配,以下是无需大规模改动原有代码的临时包装方案,仅建议用于v2框架功能验证测试:
Swift端:异步接口转同步调用
可以通过Task的value属性(Swift 5.7+支持)快速将异步方法包装为同步调用,避免修改原有同步逻辑:
// 给目标存储类添加扩展,封装同步调用方法 extension Storage { // 替换为实际的存储类名 func dataSync(forKey key: String) throws -> Data? { return try Task { try await self.data(forKey: key) }.value } }
原有代码只需替换调用:
// 原同步调用 // let data = storage?.data(forKey: key) // 替换为 let data = try? storage?.dataSync(forKey: key) return data
注意:该方式会阻塞当前线程,仅适合测试场景,生产环境请勿使用。
ObjC端:异步回调转同步调用
利用信号量dispatch_semaphore_t阻塞当前线程,等待异步回调完成,从而模拟同步调用:
// 给目标存储类添加分类,封装同步调用方法 @interface Storage (SyncTest) // 替换为实际的存储类名 - (NSData *)storedDataSyncForKey:(NSString *)key; @end @implementation Storage (SyncTest) - (NSData *)storedDataSyncForKey:(NSString *)key { __block NSData *resultData = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [self storedDataForKey:key completionHandler:^(NSData *data) { resultData = data; dispatch_semaphore_signal(semaphore); }]; // 等待回调完成,超时时间可根据实际情况调整 dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC)); return resultData; } @end
原有ObjC代码直接替换调用:
// 原同步调用 // NSData *data = [storage storedDataForKey:key]; // 替换为 NSData *data = [storage storedDataSyncForKey:key]; return data;
注意:同样会阻塞线程,测试完成后建议替换为官方推荐的异步实现,避免主线程阻塞问题。
内容的提问来源于stack exchange,提问作者TiredMagicalCoder
相关产品推荐
相关产品推荐

