刀哥多线程Barrier异步gcd-08-barrier_async

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 必须使用自定义队列,否则执行效果和全局队列一致

转载于:https://www.cnblogs.com/jiahao89/p/5118284.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值