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. g++/gcc 链接头文件 库 PATH

    转自http://blog.csdn.net/kankan231/article/details/24243871 在Linux下编译链接或运行c/c++程序时可能会遇到找不到头文件,找不到库文件的错 ...

  2. oracle错误处理及实操-【INS-20802】

    服务器硬件要求:内存>1GB,如果是虚拟机,必须设置内存为1.5G以上. 确定好主机名,安装完成以后,不要再修改主机名,一旦修改会导致oracle启动失败,注意:使用默认的localhost.l ...

  3. TCP/IP详解学习笔记(3)-- IP:网际协议

    1.概述      IP是TCP/IP协议族中最为核心的协议.所有的TCP,UDP,ICMP,IGMP数据都以IP数据报格式传输.      IP提供不可靠,无连接的数据报传送服务. 不可靠:它不能保 ...

  4. android 存储概念

    首先,我们得知道android中有内部存储(与内存要区分开来)和外部存储. 内部存储容量较小,尽量少使用,sqlite及SharePreference的数据均在内部存储当中. Log.i(" ...

  5. js object 对象 属性和方法的使用

    //object 对象 属性和方法的使用 var person = new Object(); person.name="张海"; person.age="; perso ...

  6. 关于union的那些事儿

    自从当年明月的<明朝的那些事儿>爆红之后,以***那些事儿命名的文章便层出不穷.个人认为,这样的命名通俗但具有吸引力,容易接地气.哈哈,所以我也写了几篇以<***那些事儿>的文 ...

  7. Excel2007给表格设置成只读加密属性 让他人无法修改

    在制作一些报表和公司的表格时,我们常常需要给Excel表格加密或者设置成只读属性来加以防护这些重要表格.给表格加密可以预防他人无法打开表格,只有通过输入正确的密码后才可以正常打开.设置成只读的话,可以 ...

  8. 调试时屏蔽JavaScript库代码 –Chrome DevTools Blackbox功能介绍

    代码难免会有Bug,每次我们在Chrome调试代码时,总是会进入各种各样的库代码(比如jQuery.Zepto),但实际上很多时候我们并不希望这样,要是能把这些库代码“拉黑”多好啊. 广大码农喜闻乐见 ...

  9. Java c3po

    1.准备通用类 (引用:c3p0-0.9.1.2.jar) package nankang.test; import java.sql.Connection; import com.mchange.v ...

  10. 生成.a文件步骤

    1.新建一个Project 选择 iOS->Framework & Library ->Cocoa Touch Static Library点击Next-> 输入Produc ...