iOS 开发 block 等待 block 或 block 等待

block 等待


在 iOS 开发中,如果你想要一个 block(闭包)等待执行完成,通常意味着你想要同步地执行这个 block,而不是异步地。然而,block 本身并不直接支持同步等待,因为它们是作为函数对象来设计的,可以异步地传递给其他方法或函数。

在 GCD (Grand Central Dispatch) 中,你可以使用 dispatch_sync 函数来同步执行一个 block,但这通常不推荐用于主线程,因为这会阻塞主线程,导致界面无响应。

下面是一个使用 dispatch_sync 在非主线程上同步执行 block 的例子:

objectivec 复制代码
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
dispatch_sync(queue, ^{  
    // 在这里执行你想要同步完成的任务  
    NSLog(@"This block will execute synchronously on the background queue.");  
});  
// dispatch_sync 会等待 block 执行完成后才继续执行后面的代码

请注意,如果你尝试在主线程上使用 dispatch_sync,会导致死锁,因为主线程会等待自己完成一个任务,这是不可能的。

如果你想要等待一个异步操作完成,通常的做法是使用信号量(semaphore)、回调闭包、Promise/Future 模式或者操作队列(Operation Queue)配合依赖关系。

使用信号量等待异步操作完成:

objectivec 复制代码
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);  
  
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
    // 执行异步任务  
    NSLog(@"Async task is running.");  
    sleep(2); // 模拟耗时操作  
    NSLog(@"Async task finished.");  
    dispatch_semaphore_signal(semaphore); // 发送信号表示任务完成  
});  
  
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); // 等待信号  
NSLog(@"Continuing after async task.");

使用回调闭包等待异步操作完成:

objectivec 复制代码
void (^completionBlock)(void) = ^(){  
    // 异步任务完成后执行的代码  
    NSLog(@"Continuing after async task.");  
};  
  
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
    // 执行异步任务  
    NSLog(@"Async task is running.");  
    sleep(2); // 模拟耗时操作  
    NSLog(@"Async task finished.");  
    completionBlock(); // 调用回调闭包  
});

在这些情况下,重要的是要理解你的代码是如何在并发环境中运行的,并避免潜在的竞态条件和死锁。同步等待异步操作通常应该谨慎使用,因为它们可能导致线程阻塞和性能问题。


block 等待 block

在iOS中,你可以使用GCD(Grand Central Dispatch)来执行异步操作,并在完成时执行block。如果你想等待一个block完成,你可以使用dispatch_group_wait或者dispatch_group_notify。

以下是一个使用dispatch_group_wait的例子:

objectivec 复制代码
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 
// 添加异步操作到group
dispatch_group_async(group, queue, ^{
    // 模拟耗时操作
    [NSThread sleepForTimeInterval:2];
    NSLog(@"Block 1 完成");
});
 
// 等待group中的所有任务完成
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
 
// 此处的代码会在所有block完成后执行
NSLog(@"所有block已完成");
 
// 清理group
dispatch_release(group);

如果你想在block完成时被通知而不是等待,你可以使用dispatch_group_notify:

objectivec 复制代码
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 
// 添加异步操作到group
dispatch_group_async(group, queue, ^{
    // 模拟耗时操作
    [NSThread sleepForTimeInterval:2];
    NSLog(@"Block 1 完成");
});
 
// 设置一个block在group中的任务完成时被通知
dispatch_group_notify(group, queue, ^{
    NSLog(@"所有block已完成");
});
 
// 清理group
dispatch_release(group);

在这两个例子中,我们创建了一个group,并向其添加了一个异步任务。在第一个例子中,我们使用dispatch_group_wait来等待所有任务完成,在第二个例子中,我们使用dispatch_group_notify在任务完成时得到通知。记得在完成group的操作后释放group以避免内存泄漏。

相关推荐
游戏开发爱好者818 小时前
iOS 推送怎么配置,APNs 推送证书、设备库与群发
android·ios·小程序·https·uni-app·iphone·webview
Anhty2 天前
2026 实测 4 款 AI 变声器|QQ 聊天伪装声线,告别僵硬假声
人工智能·功能测试·ios·智能手机·安卓
唔662 天前
flutter web iOS 在浏览器加载中文慢的问题
前端·flutter·ios
ZacJi2 天前
我为 DeepSeek Harness 写了一个 dsh-apple-mode 插件
ios·deepseek·vibecoding
2501_915921432 天前
抓包鹰 Traceeagle 解除证书绑定,SSL Pinning 解除
网络·网络协议·网络安全·ios·adb·https·ssl
人月神话Lee3 天前
我做了个不要账号、不要定位权限的旅行 App,聊聊那些「不做」的决定
ios·ai编程·产品
2501_916007473 天前
Bundle ID 注册与管理 App ID 创建指南 命名规则 权限开关与删除注意事项
android·ios·小程序·https·uni-app·iphone·webview
2501_915909064 天前
iOS 证书创建与管理 类型限制 p12 密码与云备份实操
android·ios·小程序·https·uni-app·iphone·webview
00后程序员张4 天前
有没有更轻量的 iOS 开发环境?快蝎kxapp轻量化路径与构成
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程