一、主队列介绍
主队列:是和主线程相关联的队列,主队列是GCD自带的一种特殊的串行队列,放在主队列中得任务,都会放到主线程中执行。如果把任务放到主队列中进行处理,那么不论处理函数是异步的还是同步的都不会开启新的线程。
获取主队列的方式:
dispatch_queue_t queue=dispatch_get_main_queue();
1)使用异步函数执行主队列中得任务,代码示例:
//1.获取主队列
dispatch_queue_t queue=dispatch_get_main_queue();
//2.把任务添加到主队列中执行
dispatch_async(queue, ^{
NSLog(@"下载图片1----%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"下载图片2----%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"下载图片3----%@",[NSThread currentThread]);
});
//打印主线程
NSLog(@"主线程----%@",[NSThread mainThread]);
总结:不会开启新的线程
2)使用同步函数,在主线程中执行主队列中得任务,会发生死循环,任务无法往下执行。示意图如下:
二、简单使用
1.在全局并发队列中,分别用异步函数和同步函数执行任务1和任务2,问:任务1和任务2是在主线程执行还是子线程执行,还是单独再开启一个新的线程?
- (void)viewDidLoad {
[super viewDidLoad];
//NSThread隐式创建线程(自动启动)
[self performSelectorInBackground:@selector(text) withObject:nil];
}
-(void)text{
NSLog(@"当前线程---%@",[NSThread currentThread]);
//创建全局的并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//异步函数
dispatch_async(queue, ^{
NSLog(@"NSLog(任务1所在的线程----%@",[NSThread currentThread]);
});
//同步函数
dispatch_sync(queue, ^{
NSLog(@"NSLog(任务2所在的线程----%@",[NSThread currentThread]);
});
}
答:任务1和任务2在不同子线程,任务1新开线程,任务2在当前线程,但都不在主线程。
2.开启子线程,加载图片
//当手指触摸屏幕的时候,从网络上下载一张图片到控制器的view上显示
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//1.获取一个全局串行队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
//2.把任务添加到队列中执行
dispatch_async(queue, ^{
//3.从网络上下载图片
NSURL *url = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee460de6182ff5e0fe99257e80.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
//4.回到主线程,展示图片
dispatch_async(dispatch_get_main_queue(), ^{
[self.button setBackgroundImage:image forState:UIControlStateNormal];
});
});
}
三、线程间的通信
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行耗时的异步操作...
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主线程,执行UI刷新操作
});
});