美文网首页iOS学习
iOS:GCD主线程

iOS:GCD主线程

作者: Henry_Jeannie | 来源:发表于2019-04-02 17:54 被阅读173次

    我们都知道在GCD中有两个很重要的概念:线程和队列。在学习的时候对这两个概念都有了一定的了解,在此做一个学习记录(仅仅是个人理解)。

    1.队列与线程

    队列不是线程,队列是用来组织需要执行的任务,将任务加到队列中,任务会按照加入到队列中的顺序(先进先出)依次执行。线程就是依次取出队列中的任务来执行,(个人理解为:就像是在食堂排队打饭,把每一个学生看成为一个任务,按照顺序排队打饭,把打饭的窗口看成是线程,食堂根据排队情况安排开设几个窗口(线程))。

    应用程序进程启动的时候主线程被系统创建,应用程序是需要不断的和用户进行交互,即主线程是需要一直存在。<NSThread: 0x600001292900>{number = 1, name = main},主线程只是系统创建的一个命名为main的线程,与其他线程应该是平等的,只不过在创建主线程的时候,主线程中加入了runloop使得主线程一直存在,不会退出。

    1.主线程只能执行主队列中的任务?

    dispatch_queue_t mainQueue = dispatch_get_main_queue();
        dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_queue_set_specific(mainQueue, "key", &"key", NULL);
        dispatch_sync(globalQueue, ^{
            BOOL result1 = [NSThread isMainThread];
            BOOL result2 = dispatch_get_specific("key") != NULL;
            NSLog(@"1111is mainThread: %d --- is mainQueue: %d", result1, result2);
        });
    

    得到结果:当前在主线程但是不是主队列,由此可以看出主线程执行了其他队列的任务。

    [10146:688118]  1111is mainThread: 1 --- is mainQueue: 0
    

    2.主队列只能在主线程中执行?

    dispatch_queue_t mainQueue = dispatch_get_main_queue();
        dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_queue_set_specific(mainQueue, "key", &"key", NULL);
        dispatch_async(globalQueue, ^{
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"is mainThread==%d",[NSThread isMainThread]);
                BOOL result2 = dispatch_get_specific("key") != NULL;
                NSLog(@"is mainQueue==%d",result2);
            });
        });
        
        dispatch_main();
    

    执行结果如下:主队列并没有在主线程中

    [10968:715046] is mainThread==0
    [10968:715046] is mainQueue==1
    

    但如果把 dispatch_main();去掉,得到的结果就正常了

    [10968:715046] is mainThread==1
    [10968:715046] is mainQueue==1
    

    dispatch_main();

     * This function "parks" the main thread and waits for blocks to be submitted
     * to the main queue. This function never returns.
    

    此函数“驻停”主线程,并等待将代码块提交到主队列,并且无法返回。
    此时是不是可以理解为:主队列任务通常是在主线程执行,当执行了dispatchMain()后,由于dispatchMain() 无法停止这个进程,只能选择强制退出,并且dispatchMain() 没有返回值,使得进程永远存在,所以系统选择让其他线程来执行主线程的任务。

    大神分析:
    多线程-奇怪的GCD

    相关文章

      网友评论

        本文标题:iOS:GCD主线程

        本文链接:https://www.haomeiwen.com/subject/anxnbqtx.html