dispatch_apply偶尔将块提交到主队列

时间:2017-08-14 07:40:39

标签: 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-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)}

我发现在“sleep 0,4,8”中,当前线程是主线程。

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

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

1 个答案:

答案 0 :(得分:0)

此日志表明您必须从主线程调用dispatch_apply

  1. 当您说“将块提交到全局队列”时,请确保将调用dispatch_apply调度到全局队列,因为这是一个同步API。

  2. dispatch_apply发送到某个后台队列时,请确保使用dispatch_async。如果您使用dispatch_sync,它可以使用当前线程作为优化。

  3. 你想要的是:

    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_async并且我将dispatch_apply放在已调度的块中,而不是相反。