Barrier 异步

  • 主要用于在多个异步操作完成之后,统一对非线程安全的对象进行更新
  • 适合于大规模的 I/O 操作

代码演练

  • 准备工作
@interface ViewController () {
// 加载照片队列
dispatch_queue_t _photoQueue;
} @property (nonatomic, strong) NSMutableArray *photoList;
@end - (NSMutableArray *)photoList {
if (_photoList == nil) {
_photoList = [[NSMutableArray alloc] init];
}
return _photoList;
}

NSMutableArray 是非线程安全的

  • viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad]; _photoQueue = dispatch_queue_create("com.itheima.com", DISPATCH_QUEUE_CONCURRENT); for (int i = 0; i < 20; ++i) {
[self loadPhotos:i];
}
}
  • 模拟下载照片并在完成后添加到数组
- (void)loadPhotos:(int)index {

    dispatch_async(_photoQueue, ^{
[NSThread sleepForTimeInterval:1.0]; NSString *fileName = [NSString stringWithFormat:@"%02d.jpg", index % 10 + 1];
NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
UIImage *image = [UIImage imageWithContentsOfFile:path]; [self.photoList addObject:image];
NSLog(@"添加照片 %@", fileName);
});
}

运行测试

  • 由于 NSMutableArray 是非线程安全的,如果出现两个线程在同一时间向数组中添加对象,会出现程序崩溃的情况

  • 解决办法

NSLog(@"添加照片 %@", fileName);
dispatch_barrier_async(_photoQueue, ^{
[self.photoList addObject:image];
NSLog(@"OK %@", [NSThread currentThread]); });

使用 dispatch_barrier_async 添加的 block 会在之前添加的 block 全部运行结束之后,才在同一个线程顺序执行,从而保证对非线程安全的对象进行正确的操作!

Barrier 工作示意图

注意:dispatch_barrier_async 必须使用自定义队列,否则执行效果和全局队列一致

刀哥多线程Barrier异步gcd-08-barrier_async的更多相关文章

  1. 刀哥多线程GCD核心概念gcd

    GCD GCD 核心概念 将任务添加到队列,并且指定执行任务的函数 任务使用 block 封装 任务的 block 没有参数也没有返回值 执行任务的函数 异步 dispatch_async 不用等待当 ...

  2. 刀哥多线程之调度组gcd-12-group

    调度组 常规用法 - (void)group1 { // 1. 调度组 dispatch_group_t group = dispatch_group_create(); // 2. 队列 dispa ...

  3. 刀哥多线程之一次性代码gcd-11-once

    一次性执行 有的时候,在程序开发中,有些代码只想从程序启动就只执行一次,典型的应用场景就是"单例" // MARK: 一次性执行 - (void)once { static dis ...

  4. 刀哥多线程现操作gcd-10-delay

    延迟操作 // MARK: - 延迟执行 - (void)delay { /** 从现在开始,经过多少纳秒,由"队列"调度异步执行 block 中的代码 参数 1. when 从现 ...

  5. 刀哥多线程全局队列gcd-09-global_queue

    全局队列 是系统为了方便程序员开发提供的,其工作表现与并发队列一致 全局队列 & 并发队列的区别 全局队列 没有名称 无论 MRC & ARC 都不需要考虑释放 日常开发中,建议使用& ...

  6. 刀哥多线程同步任务作用gcd-07-sync_task

    同步任务的作用 同步任务,可以让其他异步执行的任务,依赖某一个同步任务 例如:在用户登录之后,再异步下载文件! - (void)gcdDemo1 { dispatch_queue_t queue = ...

  7. 刀哥多线程之主队列gcd-06-main_queue

    主队列 特点 专门用来在主线程上调度任务的队列 不会开启线程 以先进先出的方式,在主线程空闲时才会调度队列中的任务在主线程执行 如果当前主线程正在有任务执行,那么无论主队列中当前被添加了什么任务,都不 ...

  8. 刀哥多线程之并发队列gcd-05-dispatch_queue_concurrent

    并发队列 特点 以先进先出的方式,并发调度队列中的任务执行 如果当前调度的任务是同步执行的,会等待任务执行完成后,再调度后续的任务 如果当前调度的任务是异步执行的,同时底层线程池有可用的线程资源,会再 ...

  9. 刀哥多线程串行队列gcd-04-dispatch_queue_serial

    串行队列 特点 以先进先出的方式,顺序调度队列中的任务执行 无论队列中所指定的执行任务函数是同步还是异步,都会等待前一个任务执行完成后,再调度后面的任务 队列创建 dispatch_queue_t q ...

随机推荐

  1. vc 判断哪个按键 被按下 消息 按键 状态

    测试Numlock 是否是亮的 环境控制台程序: #include "stdafx.h" #include <stdio.h> #include <conio.h ...

  2. windows下忘记mysql密码怎么办

    长时间不用mysql,密码忘记了怎么办,按照下面的步骤可以重新设置密码: 1.先把mysql服务停了,右键计算机-->选择管理-->选择服务和应用程序-->选择服务-->找到m ...

  3. 文件系统取证分析(第11章:NTFS概念)

    /* Skogkatt 开始翻译于2015-01-24,仅作为学习研究之用,谢绝转载. 2015-01-31更新MFT entry 属性概念. 2015-02-01翻译完成. 译注:我翻译这本书的这三 ...

  4. 百度富文本编辑器UEditor安装配置全过程

    网站开发时富文本编辑器是必不可少的,他可以让用户自行编辑内容的样式然后上传到后台!下面我们来介绍如何安装使用百度富文本编辑器 一.下载并且设置百度富文本编辑器的样式     你可以去百度UEditor ...

  5. Flash图表控件FusionCharts如何在图表标绘非连续数据

    你可能经常要以不完整的数据点绘制图表.例如,当绘制每月的销售图表时,你可能没有所有的月数据.所以,你可能只想以一个空白的区域来显示缺失的数据,不在这个区域中绘制任何东西.FusionCharts可以让 ...

  6. 【LeetCode】17. Letter Combinations of a Phone Number

    题目: 思路:设置两个List,一个存储当前层,一个存储最终层 public class Solution { public List<String> letterCombinations ...

  7. 全局变量&局部变量

    一.局部变量: 定义在函数内部的变量以及函数的形参成为局部变量 作用于:从定义那一行开始知道与其所在的代码块结束 生命周期:从程序运行到定义那一行开始分配存储空间到程序离开该变量所在的作用域 特点: ...

  8. rsync拉取远程文件

    mkdir -p   /doc sshpass -p ''pwd" rsync -avz -e 'ssh -o UserKnownHostsFile=/dev/null -o StrictH ...

  9. 正宗PC Unix实验环境

    首先解释一下PCUNIX环境,在PC服务器上可以安装多种UNIX系统例如ScoUnix,SunSolarisx86系统,BSD系统等等,但是唯一应用在生产系统(例如邮政储蓄,证券和某些银行前置机等)的 ...

  10. PAT1038. Recover the Smallest Number

    //意识到一个重要错误,一直以为atoi,itoa是windows独有的,linux下不可用,直到刚刚... //string+=比strcat好用多了,字符比较也方便的多,但是用scanf读入str ...