iOS多线程中的GCD
GCD的核心:
- 任务:执行什么操作
- 队列:用来存放任务
将任务添加到队列中,GCD会自动将队列中的任务取出,放到对应的线程中执行.
同步和异步:
dispatch_sync(<#dispatch_queue_t queue#>, <#^(void)block#>)
dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>)
同步和异步的区别:
同步:
在当前线程中执行任务,不具备开启线程的能力
异步:
在新的线程中执行任务,具备开启线程的能力.但可以不开启线程
并发:
多个任务同时执行(只有在异步函数下才有效,因为需要开启多个线程)
串行:
让任务一个接着一个的执行(有点线程同步的感觉)
用法:
// 第一个参数:给这个队列起一个名
// 第二个参数:DISPATCH_QUEUE_CONCURRENT
dispatch_queue_t myQueue = dispatch_queue_create("chaqu", DISPATCH_QUEUE_CONCURRENT);
// 接下来使用队列,并且再队列中执行一些代码
dispatch_async(myQueue, ^{
// 在这个block中写要执行的代码
NSInteger a = 0;
for (NSInteger i = 0; i < 60000001; i++) {
a++;
}
NSLog(@"%ld", a);
});
自己创建的队列,如果在这个队列中执行[下载1],[下载2],[下载3] 他会依次执行任务,但是不会在主线程执行,也就是说只会开启一条子线程.并且在 MRC下 需要手动释放这个队列-> dispatch_release(myQueue)
// GCD的第二种方法
// 通过获取主队列,然后在进行多线程的操作
// 获取主队列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^{
NSInteger a = 0;
for (NSInteger i = 0; i < 60000001; i++) {
a++;
}
NSLog(@"%ld", a);
});
// GCD的经典的用法
dispatch_async(globalQueue, ^{
// 通过子线程加载数据,然后把数据获取之后,在主线程上现实数据内容
NSString *strURL = @"http://su.bdimg.com/static/superplus/img/logo_white_ee663702.png";
NSURL *url = [NSURL URLWithString:strURL];
// 如果在主线程的时候,会卡死主线程
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [UIImage imageWithData:data];
// 把子线程里图片在主线程里显示
dispatch_async(mainQueue, ^{
// 对已经存在的图片进行赋值
NSLog(@"显示图片");
});
});
还有GCD的延迟执行:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 延时1秒之后要做的操作....
});
这里如果需要延迟x秒,在子线程做操作的话,需要将队列main_queue换成全局并发队列global_queue 就可以了
一次性代码:
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 只需要执行一次的代码,比如创建单例
});
队列组:
// 1.队列组
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 2.操作1
__block UIImage *image1 = nil;
dispatch_group_async(group, queue, ^{
// 执行下载超大图片1
});
// 3.下载图片2
__block UIImage *image2 = nil;
dispatch_group_async(group, queue, ^{
// 执行下载微小图片2
});
// 4.提示下载完成 (保证执行完组里面的所有任务之后,再执行notify函数里面的block)
dispatch_group_notify(group, queue, ^{
// 提示下载完成
});
notify的block会等group里的所有queue的任务都执行完之后才会回调.
常用的应该就是以上,以后发现了别的GCD用法,再补上.
网友评论