多執行緒:barrier的使用

CG-L發表於2016-03-25
//
//  ViewController.m
//  12-barrier使用
//
//  Created by gzxzmac on 16/1/29.
//  Copyright © 2016年 gzxzmac. All rights reserved.
//

#import "ViewController.h"

@interface ViewController () {
    dispatch_queue_t _queue;
}
@property (nonatomic, strong) NSMutableArray *photoList; // 儲存下載好的圖片
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self download];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"下載了 %zd 張圖片",self.photoList.count);
}

// 最快速建立一個可變的陣列  @[].mutableCopy
- (NSMutableArray *)photoList {
    if (_photoList == nil) {
        _photoList = [NSMutableArray array];
    }
    return _photoList;
}

- (void)download {

    // NSArray,字典,NSData,..... 執行緒安全
    // 所有的可變的物件(字典,陣列,data) 非執行緒安全
    /*
     NSArchiver
     NSAutoreleasePool
     NSBundle
     NSCalendar
     NSCoder
     NSCountedSet
     NSDateFormatter
     NSEnumerator
     NSFileHandle
     NSFormatter
     NSHashTable functions
     NSInvocation
     NSJavaSetup functions
     NSMapTable functions
     NSMutableArray
     NSMutableAttributedString
     NSMutableCharacterSet
     NSMutableData
     NSMutableDictionary
     NSMutableSet
     NSMutableString
     NSNotificationQueue
     NSNumberFormatter
     NSPipe
     NSPort
     NSProcessInfo
     NSRunLoop
     NSScanner
     NSSerializer
     NSTask
     NSUnarchiver
     NSUndoManager
     */
    // 一定要使用自定義的併發佇列
    _queue = dispatch_queue_create("itcast", DISPATCH_QUEUE_CONCURRENT);
    for (int i = 0; i < 1000; ++i) {
        dispatch_async(_queue, ^{
            NSLog(@"下載圖片%d",i);
            [NSThread sleepForTimeInterval:0.5];
            // 模擬下載
            NSString *imageName = [NSString stringWithFormat:@"%d.jpg",i % 9];
            NSString *path = [[NSBundle mainBundle]pathForResource:imageName ofType:nil];

            UIImage *image = [UIImage imageWithContentsOfFile:path];

            // 使用barrier 之後,全部下載完之後,再統一儲存
            // 減少多條執行緒搶奪資源的問題
            // 在工作中基本不怎麼使用(知道)
            dispatch_barrier_async(_queue, ^{
                if (image == nil) {
                    NSLog(@"%d -- %@",i,path);
                }
                NSLog(@"儲存圖片%@",[NSThread currentThread]);
                // 避免多個執行緒搶同一塊資源
                [self.photoList addObject:image];
            });
        });
    }
}

@end

相關文章