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

Objective-C中如何让带返回值的方法等待异步block执行完成后返回

你代码中存在的核心问题是createPDFFromEmail:completionHandler:的completionHandler是异步回调,原方法执行到return语句时,回调block还未触发,returnValue还没被赋值,最终返回的是未初始化的错误值。
有两种常用重构方案,分别适配不同的使用场景:

方案1:使用GCD信号量同步等待block执行(仅适合子线程调用场景)

通过信号量阻塞当前线程,直到block执行完成再继续执行return逻辑,代码如下:

- (long)someMethod {
    long returnValue;
    // 初始化计数为0的信号量
    dispatch_semaphore_t sem = dispatch_semaphore_create(0);
    [MFPDFConverter createPDFFromEmail:emailToConvert completionHandler:^(long longObtainedFromBlock) {
        NSLog(@"Here we are");
        returnValue = longObtainedFromBlock;
        // block执行完成,信号量计数+1
        dispatch_semaphore_signal(sem);
    }];
    // 阻塞当前线程,直到信号量计数≥1才继续执行,计数同时-1
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    return returnValue;
}

注意事项:

  • 该方案会阻塞当前调用线程,如果在主线程调用会导致界面无响应卡死,绝对禁止主线程使用
  • 如果异步操作可能失败永远不触发回调,建议把等待超时时间改成具体值,避免永久卡住

方案2:重构为异步回调模式(最推荐,符合iOS开发规范)

异步操作本身不应该设计为同步返回的方法,直接修改方法结构,把最终结果通过回调抛出,完全不会阻塞线程,代码如下:

// 修改方法签名:无返回值,新增回调参数接收最终结果
- (void)getPDFValueWithEmail:(NSString *)emailToConvert completion:(void(^)(long resultValue))completion {
    [MFPDFConverter createPDFFromEmail:emailToConvert completionHandler:^(long longObtainedFromBlock) {
        NSLog(@"Here we are");
        // 回调判空避免崩溃
        if (completion) {
            completion(longObtainedFromBlock);
        }
    }];
}

调用示例:

// 调用时在回调里处理后续逻辑
[self getPDFValueWithEmail:emailToConvert completion:^(long resultValue) {
    NSLog(@"拿到最终返回值:%ld", resultValue);
    // 后续拿到结果后的业务逻辑都写在这里
}];

注意事项:

  • 该方案不会阻塞任何线程,主线程调用也不会影响界面响应,是iOS异步场景的标准实现方式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 22:54:10