Objective-C:含Block的方法如何返回NSDictionary对象
嘿,这个问题其实是异步编程里的常见坑——你这里的readFromApi:是个异步方法,它的回调block会在API请求完成后才执行,但你的searcherMethod会在调用readFromApi:之后立刻就执行完返回了,所以你在block里写的return response根本不会让searcherMethod拿到这个值。
下面给你几种可行的解决办法,按推荐程度排序:
1. 改用回调Block(最推荐的异步方案)
这是iOS开发里处理异步操作的标准方式,把方法的返回值改成void,然后新增一个completion block参数,在API请求完成后把结果通过这个block传出去:
- (void)searcherMethod:(NSString *)text completion:(void (^)(NSDictionary *response))completion { [ReadService readFromApi:APIURL whenFinish:^(id responseObject) { NSDictionary *response = (NSDictionary*)responseObject; // 确保在主线程回调(如果需要更新UI的话) if (completion) { dispatch_async(dispatch_get_main_queue(), ^{ completion(response); }); } }]; }
调用的时候就这么用:
[self searcherMethod:@"yourText" completion:^(NSDictionary *response) { // 在这里处理返回的response字典 NSLog(@"拿到结果:%@", response); }];
这种方式不会阻塞线程,完全符合异步编程的设计,也是苹果推荐的做法。
2. 用GCD信号量强制同步(谨慎使用)
如果你非要让searcherMethod同步返回结果,可以用GCD的信号量来等待异步操作完成,但绝对不能在主线程调用这个方法,否则会造成死锁(因为很多网络库的回调是在主线程执行的,信号量会卡住主线程,导致回调永远无法执行):
- (NSDictionary *)searcherMethod:(NSString *)text { __block NSDictionary *result = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [ReadService readFromApi:APIURL whenFinish:^(id responseObject) { result = (NSDictionary*)responseObject; // 发送信号,告诉等待的线程可以继续了 dispatch_semaphore_signal(semaphore); }]; // 等待异步操作完成,超时时间可以自己设置,比如10秒 dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC)); return result; }
⚠️ 注意:如果在主线程调用这个方法,会导致UI卡死,甚至APP崩溃,所以只适合在后台线程使用。
3. 改用同步网络请求(不推荐)
有些网络库支持同步请求,你可以把readFromApi:改成同步版本,但这种方式会阻塞当前线程,要是在主线程调用,用户会明显感觉到APP卡顿,严重影响体验,所以非常不建议这么做。
总结一下,优先用第一种回调Block的方式,这是最优雅也最安全的解决方案。
内容的提问来源于stack exchange,提问作者doxsi
相关产品推荐
相关产品推荐

