Dispatch_sync всегда планирует блок на главной теме
Я выполняю блок с использованием dispatch_sync, и блок выполняется правильно. Но этот блок выполняется на основном потоке. Согласно Apple Doc:
Последовательные очереди (также известные как частные очереди отправки) выполняют одну задачу в то время в том порядке, в котором они добавляются в очередь. The выполняемые в настоящее время задачи выполняются на отдельном потоке (который может меняться от задачи к задаче), которая управляется очередью отправки.
что означает (или то, что я понял), что текущий исполняемый процесс будет выполняться в отдельном потоке.
Ниже приведен код, который я использую, чтобы судить о том, что происходит. Он вызывается внутри NSURLConnection didReceiveData: метод делегирования (я знаю, что не должен делать это внутри метода didReceiveData: delegate, но это всего лишь образец для фокусировки на dispatch_sync). Ниже приведены различные способы, которые я могу принять в качестве доказательства моего заключения:
-
Использование dispatch_sync в Глобальной параллельной очереди
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if ([NSThread isMainThread]) {
NSLog(@"Main Thread");
}
else
NSLog(@"Not on Main Thread");
//Some Process
});
Выход -
Main Thread
Main Thread
Main Thread
// Main Thread printed till didReceiveData: gets called
-
Использование dispatch_sync в собственной созданной очереди с помощью dispatch_queue_create
// Create queue somewhere else like this
dispatch_queue_t newQueue = dispatch_queue_create("WriteQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(newQueue, ^{
if ([NSThread isMainThread]) {
NSLog(@"Main Thread");
}
else
NSLog(@"Not on Main Thread");
//Some Process
});
Выход -
Main Thread
Main Thread
Main Thread
// Main Thread printed till didReceiveData: gets called
Я немного удивлен здесь, блок выполняется всегда в основном потоке, или я что-то упускаю. Думаю, что это похоже на Apple Doc. Кто-нибудь знает, что это такое?
Обновление. Как и в других дискуссиях, я понимаю, что dispatch_sync выполняет блок в одном и том же потоке (в большинстве случаев), то почему заявления apple docs в некоторых отношениях противоречат друг другу. Почему apple говорит: "Выполняемая в данный момент задача выполняется в отдельном потоке (который может варьироваться от задачи к задаче), который управляется очередью отправки".
Или я все еще что-то пропустил?
Ответы
Ответ 1
dispatch_sync() отправляет блок в тот же поток, что и в нормальном режиме.
ИЗМЕНИТЬ
Apple Documentation не только говорит об этом, но и говорит следующее:
В качестве оптимизации эта функция, когда это возможно, вызывает блок в текущем потоке.
В качестве побочного примечания (я знаю, что вы говорите об синхронной версии, но предопределяете это), я бы сказал, что также dispatch_async() может вызвать выполнение нескольких блоков в одном потоке.
Ответ 2
Для фона блока используйте
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// background code
});
Обратите внимание: _async, а не _sync
EDIT: аналогично, чтобы выполнить что-то в основном потоке, используйте
dispatch_async(dispatch_get_main_queue(), ^{
// main thread code
});
Ответ 3
Важно понимать, что Grand Central Dispatch может гарантировать, что блок, отправленный в основную очередь, будет работать в основном потоке, но блок, отправленный в любую другую очередь, не имеет никаких гарантий относительно того, какой поток будет выполняться блок.
Никакой гарантии относительно того, на какой поток будет вызываться блок; однако гарантируется, что одновременно будет вызываться только один блок, отправленный в очередь отправки FIFO.
Grand Central Dispatch управляет пулом потоков и как можно больше использует существующие потоки. Если основной поток доступен для работы (т.е. В режиме ожидания), блок может быть выполнен в этом потоке.
Ответ 4
Вот как вы можете это сделать в Swift:
runThisInMainThread { () -> Void in
// Runs in the main thread
}
func runThisInMainThread(block: dispatch_block_t) {
dispatch_async(dispatch_get_main_queue(), block)
}
Он включен как стандартная функция в моем репо, проверьте его: https://github.com/goktugyil/EZSwiftExtensions