iOS 主队列与主线程

896 阅读3分钟

队列:存放要执行的任务.

线程:执行任务.

二者关系:线程去队列里面获取任务进行执行.

然后我们来看主队列与主线程:

  • 应用程序被创建之后会自主创建一个队列和线程,被称为主队列和主线程.而且一个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 是需要立即执行的,但是主线程正在处理事情,这就造成了死锁.