iOS 开发 block 等待 block 或 block 等待

news/2024/4/27 17:15:38

 block 等待


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

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

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

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)配合依赖关系。

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

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.");

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

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的例子:

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:

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以避免内存泄漏。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.cpky.cn/p/10906.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

如何写好Stable Diffusion的prompt

Stable Diffusion是一种强大的文本到图像生成模型,其效果在很大程度上取决于输入的提示词(Prompt)。以下是一些关于如何编写有效的Stable Diffusion Prompt的秘诀: 明确描述:尽量清晰地描述你想要的图像内容。使用具体…

SpringBoot-04 | spring-boot-starter-logging原理原理

SpringBoot-04 | spring-boot-starter-logging原理原理 第一步:springboot加载factories文件第二步:构造监听器第三步:注册监听器到Spring中第四步:开始加载日志框架第五步:加载日志框架logback-spring.xml第六步&…

Wireshark 抓包工具与长ping工具pinginfoview使用,安装包

一、Wireshark使用 打开软件,选择以太网 1、时间设置时间显示格式 这个时间戳不易直观,我们修改 2、抓包使用的命令 1)IP地址过滤 ip.addr192.168.1.114 //筛选出源IP或者目的IP地址是192.168.1.114的全部数据包。 ip.sr…

Java有哪些常用的集合?

1、典型回答 在 Java 中,常用的集合有以下几个: 列表(List):有序集合,可以包含重复元素。常见实现类有 ArrayList、LinkedList、 Vector 等集合(Set):无序集合,不允许包含重复元素。常见实现类有 HashSet、…

【Flask开发实战】防火墙配置文件解析(二)之shell读取内容

一、前言 上一篇文章中,介绍了防火墙配置文件包含的基本元素和格式样式,并模拟了几组有代表性的规则内容,作为基础测试数据。在拿到基础测试数据后,关于我们最终想解析成的数据是什么样式的,其实不难看出,…

【算法杂货铺】分治

目录 🌈前言🌈 📁 快速排序 📂75. 颜色分类 - 力扣(LeetCode) 📂 912. 排序数组 - 力扣(LeetCode) 📂 215. 数组中的第K个最大元素 - 力扣(Lee…