使用GCD阻塞本文主要用途是解决多线程资源共享问题
主要用于在多个异步操作完成后,统一对非线程安全的对象进行操作。
定义图片容器(非线程安全的);
@interface ViewController ()
// 图片数组
@property (nonatomic,strong) NSMutableArray *imagesArray;
@end
由于imageArray是非线程安全的,所以当两个线程在同一时间向数组添加对象的时候会出现崩溃的现象。
解决办法: 添加barrier
// 自定义队列
dispatch_queue_t queue = dispatch_queue_create("sign", DISPATCH_QUEUE_CONCURRENT);
dispatch_barrier_async(queue, ^{
// 图片下载完成之后添加到数组
[self.imagesArray
addObject:image];
NSLog(@"barrier %@ %@",name,[NSThread currentThread]);
});
正确的下载方式:
- (void)downloadImages
{
// 自定义队列
dispatch_queue_t queue = dispatch_queue_create("sign", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 1000; i++) {
dispatch_async(queue, ^{
// 拼接图片名字
NSString *name = [NSString stringWithFormat:@"%02d.jpg",(i%10) + 1];
// 获取图片在本地的地址
NSURL *URL = [[NSBundle mainBundle] URLForResource:name withExtension:nil];
NSData *data = [NSData dataWithContentsOfURL:URL];
UIImage *image = [UIImage imageWithData:data];
NSLog(@"%@ %@",name,[NSThread currentThread]);
dispatch_barrier_async(queue, ^{
// 图片下载完成之后添加到数组
[self.imageArray addObject:image];
NSLog(@"barrier %@ %@",name,[NSThread currentThread]);
});
});
}
}
用dispatch_barrier_async添加的block会在之前添加的block全部运行结束后才会在同一线程顺序执行,从而保证了非线程安全对象的安全操作。