当前位置: 首页 > news >正文

iOS 开发 block 等待 block 或 block 等待

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

相关文章:

  • 基于opencv的图像处理系统的设计与实现
  • 如何在“Microsoft Visual Studio”中使用OpenCV编译应用程序
  • spring boot-操作excel(EasyExcel 快速开始)/ spring boot接受文件参数 File
  • 如何在Windows系统搭建Emby影音平台并实现远程访问本地文件【内网穿透】
  • 二进制安全找实习记录
  • unity内存优化之AB包篇(微信小游戏)
  • 动手学习深度学习之环境配置
  • STM32中MicroLIB的关闭为什么会导致卡死----解析
  • 【数据结构】堆
  • zookeeper快速入门二:zookeeper基本概念
  • 145 Linux 网络编程1 ,协议,C/S B/S ,OSI 7层模型,TCP/IP 4层模型,
  • 2.3 物理层设备
  • 开发K8S Operator
  • [Django 0-1] Core.Checks 模块
  • 传统电力运维企业的数字化转型案例
  • Android Volley源码解析
  • Codepen 每日精选(2018-3-25)
  • gulp 教程
  • input实现文字超出省略号功能
  • JavaScript 基本功--面试宝典
  • JavaScript标准库系列——Math对象和Date对象(二)
  • JavaScript设计模式之工厂模式
  • Java深入 - 深入理解Java集合
  • Koa2 之文件上传下载
  • MySQL-事务管理(基础)
  • react-native 安卓真机环境搭建
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 从tcpdump抓包看TCP/IP协议
  • 浮动相关
  • 缓存与缓冲
  • 回顾 Swift 多平台移植进度 #2
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 国内开源镜像站点
  • # Apache SeaTunnel 究竟是什么?
  • #Linux(帮助手册)
  • #pragma 指令
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (day 12)JavaScript学习笔记(数组3)
  • (python)数据结构---字典
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (solr系列:一)使用tomcat部署solr服务
  • (TOJ2804)Even? Odd?
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (一)硬件制作--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • (转)创业家杂志:UCWEB天使第一步
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • ***详解账号泄露:全球约1亿用户已泄露
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET Framework 服务实现监控可观测性最佳实践
  • .net framework4与其client profile版本的区别
  • .Net Winform开发笔记(一)