block: block是c的一个运行时特性,和函数指针类似,用户回调函数。主要用于并行线程。
//创建一个分发队列,第一个参数为队列名,第二个参数是保留的 dispatch_queue 属性,设为null //可使用函数 dispatch_queue_t dispatch_get_global_queue(long priority, unsigned long flags);来获得全局的 dispatch_queue,参数 priority 表示优先级, dispatch_queue_t queue = dispatch_queue_create("test_queue", NULL); //dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) //将一个 block 加入一个 dispatch_queue,这个 block 会再其后得到调度时,并行运行。一个queue可以加入多个block,这些 blocks 是按照 FIFO(先入先出)规则调度的,先加入的先执行,后加入的一定后执行,但在某一个时刻,可能有多个 block 同时在执行。实际结果是第一个执行完执行第二个。 dispatch_sync(queue, ^(void){ for (int i=0; i<100; ++i) { NSLog(@"i:%d", i); } });
信号:sem
//创建信号,将其资源初始值设置为 0 (不能少于 0),表示任务还没有完成,没有资源可用主线程不要做事情。 __block dispatch_semaphore_t sem = dispatch_semaphore_create(0); __block dispatch_semaphore_t sem2 = dispatch_semaphore_create(0); dispatch_queue_t queue = dispatch_queue_create("test_queue", NULL); dispatch_sync(queue, ^(void){ for (int i=0; i<100; ++i) { NSLog(@" block 1 i:%d", i); } //增加 semaphore 计数(可理解为资源数),表明任务完成,有资源可用主线程可以做事情了。 dispatch_semaphore_signal(sem); }); dispatch_sync(queue, ^(void){ dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); for (int i=0; i<100; ++i) { NSLog(@" block 2 i:%d", i); } dispatch_semaphore_signal(sem2); }); //等待信号,主线程继续运行,减少 semaphore 的计数,如果资源数少于 0,则表明资源还可不得,我得按照FIFO(先等先得)的规则等待资源就绪,一旦资源就绪并且得到调度了,我再执行。 dispatch_semaphore_wait(sem2, DISPATCH_TIME_FOREVER); dispatch_release(queue); dispatch_release(sem);
group
将block加入到group,group中所有block执行完之后,主线程才可以继续运行
//创建信号,将其资源初始值设置为 0 (不能少于 0),表示任务还没有完成,没有资源可用主线程不要做事情。 __block dispatch_semaphore_t sem = dispatch_semaphore_create(0); dispatch_queue_t queue = dispatch_queue_create("test_queue", NULL); dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, queue, ^(void){ for (int i=0; i<100; ++i) { NSLog(@" block 1 i:%d", i); } //增加 semaphore 计数(可理解为资源数),表明任务完成,有资源可用主线程可以做事情了。 dispatch_semaphore_signal(sem); }); dispatch_block_t block2 = ^(void){ dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); for (int i=0; i<100; ++i) { NSLog(@" block 2 i:%d", i); } }; dispatch_group_async(group, queue, block2); //主线程等待block执行完成 dispatch_group_wait(group, DISPATCH_TIME_FOREVER); dispatch_release(group); dispatch_release(queue); dispatch_release(sem);
子线程运行完
dispatch_async(getDataQueue,^{ //获取数据,获得一组后,刷新UI. dispatch_aysnc (mainQueue, ^{ //UI的更新需在主线程中进行 }; } )
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?