Ios 调度\u偶尔向主队列应用提交块

Ios 调度\u偶尔向主队列应用提交块,ios,objective-c,multithreading,grand-central-dispatch,Ios,Objective C,Multithreading,Grand Central Dispatch,我有以下代码: dispatch_apply(10, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index) { [NSThread sleepForTimeInterval:index]; NSLog(@"sleep %lu, in thread %@",index,[NSThread currentThread]); }); 在主线程中运行时,在控制台中打印: 2017-0

我有以下代码:

dispatch_apply(10, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index) {
    [NSThread sleepForTimeInterval:index];
    NSLog(@"sleep %lu, in thread %@",index,[NSThread currentThread]);
});
在主线程中运行时,在控制台中打印:

2017-08-14 15:24:53.812 TestGCD[21480:4127352] sleep 0, in thread <NSThread: 0x600000067d40>{number = 1, name = main}
2017-08-14 15:24:54.816 TestGCD[21480:4127420] sleep 1, in thread <NSThread: 0x600000072100>{number = 3, name = (null)}
2017-08-14 15:24:55.816 TestGCD[21480:4127435] sleep 2, in thread <NSThread: 0x600000072180>{number = 4, name = (null)}
2017-08-14 15:24:56.815 TestGCD[21480:4127422] sleep 3, in thread <NSThread: 0x6080000731c0>{number = 5, name = (null)}
2017-08-14 15:24:57.813 TestGCD[21480:4127352] sleep 4, in thread <NSThread: 0x600000067d40>{number = 1, name = main}
2017-08-14 15:24:59.818 TestGCD[21480:4127420] sleep 5, in thread <NSThread: 0x600000072100>{number = 3, name = (null)}
2017-08-14 15:25:01.822 TestGCD[21480:4127435] sleep 6, in thread <NSThread: 0x600000072180>{number = 4, name = (null)}
2017-08-14 15:25:03.821 TestGCD[21480:4127422] sleep 7, in thread <NSThread: 0x6080000731c0>{number = 5, name = (null)}
2017-08-14 15:25:05.815 TestGCD[21480:4127352] sleep 8, in thread <NSThread: 0x600000067d40>{number = 1, name = main}
2017-08-14 15:25:08.824 TestGCD[21480:4127420] sleep 9, in thread <NSThread: 0x600000072100>{number = 3, name = (null)}
2017-08-14 15:24:53.812testgcd[21480:4127352]睡眠0,在线程{number=1,name=main}
2017-08-14 15:24:54.816 TestGCD[21480:4127420]sleep 1,在线程{number=3,name=(null)}
2017-08-14 15:24:55.816 TestGCD[21480:4127435]sleep 2,在线程{number=4,name=(null)}
2017-08-14 15:24:56.815testgcd[21480:4127422]sleep3,在线程{number=5,name=(null)}
2017-08-14 15:24:57.813 TestGCD[21480:4127352]sleep 4,在线程{number=1,name=main}中
2017-08-14 15:24:59.818 TestGCD[21480:4127420]sleep 5,在线程{number=3,name=(null)}
2017-08-14 15:25:01.822 TestGCD[21480:4127435]sleep 6,在线程{number=4,name=(null)}
2017-08-14 15:25:03.821 TestGCD[21480:4127422]sleep 7,在线程{number=5,name=(null)}
2017-08-14 15:25:05.815 TestGCD[21480:4127352]sleep 8,线程{number=1,name=main}
2017-08-14 15:25:08.824 TestGCD[21480:4127420]sleep 9,在线程{number=3,name=(null)}
我发现在“睡眠0,4,8”中,当前线程是主线程

sleep 0, in thread <NSThread: 0x600000067d40>{number = 1, name = main}
sleep 0,在线程{number=1,name=main}

为什么我将块提交到全局队列,但偶尔会在主队列上调用它?

此日志表明您一定是从主线程调用了
dispatch\u apply

  • 当您说“将块提交到全局队列”时,请确保将调用分派到
    dispatch\u apply
    到全局队列,因为这是一个同步API

  • dispatch\u apply
    分派到某个后台队列时,请确保使用
    dispatch\u async
    。如果使用
    dispatch\u sync
    它可以使用当前线程作为优化

  • 你想要的是:

    NSLog(@"starting on thread %@",[NSThread currentThread]);
    
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
        dispatch_apply(10, dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^(size_t index) {
            [NSThread sleepForTimeInterval:index];
            NSLog(@"sleep %lu, in thread %@",index,[NSThread currentThread]);
        });
    });
    

    请注意,我使用的是
    dispatch\u async
    ,我将
    dispatch\u apply
    放在已调度块中,而不是相反。

    此日志表明您必须从主线程调用
    dispatch\u apply

  • 当您说“将块提交到全局队列”时,请确保将调用分派到
    dispatch\u apply
    到全局队列,因为这是一个同步API

  • dispatch\u apply
    分派到某个后台队列时,请确保使用
    dispatch\u async
    。如果使用
    dispatch\u sync
    它可以使用当前线程作为优化

  • 你想要的是:

    NSLog(@"starting on thread %@",[NSThread currentThread]);
    
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
        dispatch_apply(10, dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^(size_t index) {
            [NSThread sleepForTimeInterval:index];
            NSLog(@"sleep %lu, in thread %@",index,[NSThread currentThread]);
        });
    });
    

    注意,我使用的是
    dispatch\u async
    ,我将
    dispatch\u apply
    放在调度块中,而不是相反。

    您可能应该澄清线程和队列之间的区别。在主队列上调度的任务将始终在主线程上执行。在另一个队列上调度的任务可以在主线程上执行。检查当前线程无法告诉您有关调度任务的队列的任何信息。(好吧,我想如果当前线程不是主线程,那么您就知道任务没有在主队列上调度)嗯,有两个要点:首先,同步地向某个队列调度代码实际上会尽可能在当前线程上运行(例如,如果您从主线程调用
    dispatch\u sync
    到全局队列,则调度的任务将在主线程上运行,不管如何)。其次,当您执行
    dispatch\u apply
    (同步)时,当前线程“参与”。因此,如果从主线程
    dispatch\u apply
    ,则主线程将是它使用的线程之一。您可能应该澄清线程和队列之间的区别。在主队列上调度的任务将始终在主线程上执行。在另一个队列上调度的任务可能在主线程上执行。检查当前线程不能告诉您任何关于调度任务的队列的信息。(好吧,我想如果当前线程不是主线程,那么您就知道任务没有调度到主队列上)IMHO,有两个要点:首先,同步地向某个队列发送代码实际上会尽可能在当前线程上运行(例如,如果您从主线程调用
    dispatch\u sync
    到全局队列,则调度的任务将在主线程上运行,不管如何)。其次,当您执行
    dispatch\u apply
    (同步)时,当前线程“参与”因此,如果从主线程
    dispatch\u apply
    ,则主线程将是它使用的线程之一。