GCD中的一些高级特性

在开发中执行比较耗时的程序的时候,我们通常都是运用多线程的方式来处理的,在iOS的开发中我们可以使用GCD来处理,一旦用到了多线程就不可避免的会出现线程之间的锁的问题(死锁,读写锁,互斥锁等等)。下面我们就来谈谈在GCD中如何避免多线程操作的读写锁以前其他的一些特性。

1.运用GCD避免读写锁导致线程安全问题

假设,我们有一个DataManager类,它用来管理整个程序中的数据,再操作的时候就会出现添加数据和读取数据的操作,如果在同一个时间点,两个线程同时要对数据进行添加操作的话,则就会发生操作错误的问题,为了解决这个我们运用到GCD中的barrier和sync操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@interface DataManager ()

@property (strong, nonatomic) NSMutableArray *dataArray;
@property (strong, nonatomic) dispatch_queue_t concurrentDataQueue;

@end

@implementation DataManager

+ (instancetype)shareInstance {
static DataManager *dataManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dataManager = [[DataManager alloc] init];
dataManager.concurrentDataQueue = dispatch_queue_create("com.kingiol.gcd.dataManagerQueue", DISPATCH_QUEUE_CONCURRENT);
});
return dataManager;
}

- (NSArray *)data {
__block NSArray *returnData = nil;
dispatch_sync(self.concurrentDataQueue, ^{
returnData = [_dataArray copy];
});
return returnData;
}

- (void)addData:(id)data {
if (data) {
dispatch_barrier_async(self.concurrentDataQueue, ^{
[_dataArray addObject:data];
});
}
}

@end

通过上述的代码就能够很好的处理多线程对dataArray数组的操作,并且不会出现读写锁的问题。

2.运用GCD的group来监听一组并发是否运行结束

如果当前有3张图片,我们需要从网络上面下载,然后全部下载完成之后,我们需要统一的提醒用户下载完成,这个时候因为每一个图片下载都是并发的,传统的方法是每一个线程各自都有一个bool变量,然后我们去魂环判断这么变量是不是都被置成已完成的状态。现在我们来运用GCD中的group特性来统一处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
dispatch_group_t downloadGroup = dispatch_group_create();
for (NSInteger i = 0; i < 3; i++) {
dispatch_group_enter(downloadGroup);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//下载图片程序
//在图片下载完成的block中调用:
dispatch_group_leave(downloadGroup);
});
}
dispatch_group_notify(downloadGroup, dispatch_get_main_queue(), ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"全部下载完成" delegate:nil cancelButtonTitle:@"cancel" otherButtonTitles:nil, nil];
[alertView show];
});
文章目录
  1. 1. 1.运用GCD避免读写锁导致线程安全问题
  2. 2. 2.运用GCD的group来监听一组并发是否运行结束
,