zoukankan      html  css  js  c++  java
  • 刀哥多线程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 必须使用自定义队列,否则执行效果和全局队列一致

  • 相关阅读:
    第十四周学习进度
    第十三周学习进度
    第十二周学习进度条
    从用户体验角度评价所使用的输入法。
    个人博客十
    数组测试 --Junit
    看了build to win之后的感想
    思考题
    数组中最大子数组之和
    使用Espresso进行UI测试
  • 原文地址:https://www.cnblogs.com/jiahao89/p/5118284.html
Copyright © 2011-2022 走看看