队列:存放要执行的任务.
线程:执行任务.
二者关系:线程去队列里面获取任务进行执行.
然后我们来看主队列与主线程:
- 应用程序被创建之后会自主创建一个队列和线程,被称为主队列和主线程.而且一个App只会包含一个主队列和主线程.二者是匹配的.
- 主队列是系统自动为我们创建的一个串行队列,在每个应用程序只有一个主队列,专门负责调度主线程里的任务 日常我们在开发过程中都会使用如下代码来回到主线程:
dispatch_async(dispatch_get_main_queue(), ^{
// doSomthings
});
main_queue: 是主队列,上面的代码是回到主队列.
那为什么这样写可以回到主线程呢,前面说了,主线程和主队列唯一,且主队列的任务只能在主线程中执行,尽管主队列里的某个任务是异步执行,也是会在主线程中执行.只是要等到主线程有时间来处理这个异步操作.
NSLog(@"begin");
for (int i = 0 ; i < 10; i ++) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"current Thread: %@; Task: %@",[NSThread currentThread], @(i));
});
}
NSLog(@"end");
2016-08-28 21:22:18.384 Test[72358:1633765] begin
2016-08-28 21:22:18.384 Test[72358:1633765] end
2016-08-28 21:22:18.388 Test[72358:1633765] isMainThread: 1; Task: 0
2016-08-28 21:22:18.388 Test[72358:1633765] isMainThread: 1; Task: 1
2016-08-28 21:22:18.388 Test[72358:1633765] isMainThread: 1; Task: 2
2016-08-28 21:22:18.388 Test[72358:1633765] isMainThread: 1; Task: 3
2016-08-28 21:22:18.389 Test[72358:1633765] isMainThread: 1; Task: 4
那这样就会有疑问?
1.主线程只能执行主队列里的任务吗?
我们来看下代码:
- (void) text {
NSLog(@"isMainThread: %@", @([NSThread isMainThread]));
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"isMainThread: %@", @([NSThread isMainThread]));
});
}
同步执行一个全局并发队列里的任务
2016-08-28 21:55:26.262 Test[72533:1649394] isMainThread: 1
2016-08-28 21:55:26.263 Test[72533:1649394] isMainThread: 1
答案:yes
这下再来理解一下:死锁
-(void)testMain{
//:main
NSLog(@"begin");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"current Thread: %@; Task: %@",[NSThread currentThread], @(i));
});
NSLog(@"end");
}
主线程执行begin,开始执行同步操作,但是同步操作是打印current Thread 这一步,也需要在主线程中执行,但是主线程正在执行 testMain还没执行完成,这个时候像主队列里面添加任务这个任务是不被执行的,因为主线程没时间处理这个添加进来的任务,但是dispatch_sync 是需要立即执行的,但是主线程正在处理事情,这就造成了死锁.