Использование GCD - это текущая официальная рекомендация и требует меньше усилий, чем любое другое решение. Если вам явно необходимо, чтобы вещи, которые вы передаете, происходили последовательно (то есть, как если бы они находились в одном потоке), тогда вы можете достичь этого, но, вероятно, разумнее просто изменить, например,
[self doCostlyTask];
Кому:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^()
{
[self doCostlyTask];
dispatch_async(dispatch_get_main_queue(), ^()
{
// most UIKit tasks are permissible only from the main queue or thread,
// so if you want to update an UI as a result of the completed action,
// this is a safe way to proceed
[self costlyTaskIsFinished];
});
});
Это, по сути, говорит ОС: «делайте этот код с низким приоритетом там, где это будет наиболее эффективно». Различные вещи, которые вы публикуете в любой из глобальных очередей, могут или не могут выполняться в том же потоке, что и другие, и в качестве потока, который их отправил, и могут или не могут происходить одновременно. ОС применяет правила, которые она считает оптимальными.
Экспозиция:
GCD - это реализация Apple пула потоков, и они в то же время представили замыкания (как «блоки»), чтобы сделать его пригодным для использования. Таким образом, синтаксис ^(C-style args){code}
является блоком / закрытием. То есть это код плюс состояние любых переменных (подлежащих предупреждению), на которые ссылается код. Вы можете хранить и вызывать блоки самостоятельно без знания или использования GCD.
dispatch_async
- функция GCD выдает блок в назначенную очередь. Он выполняет блок в некотором потоке в некоторое время и применяет неуказанные внутренние правила, чтобы сделать это оптимальным образом. Он будет судить по таким факторам, как количество ядер, которые у вас есть, насколько они заняты, что они в данный момент думают об энергосбережении (которое может зависеть от источника питания), как работают энергопотребление для конкретного процессора и т. Д.
Итак, когда программист разрабатывается, блоки превращают код в нечто, что вы можете передать в качестве аргумента. GCD позволяет вам запрашивать, чтобы блоки выполнялись в соответствии с наилучшим планированием, которым может управлять ОС. Блоки очень легкие для создания и копирования - намного больше, чем, например, NSOperation
s.
GCD выходит за рамки базовой асинхронной диспетчеризации в приведенном выше примере (например, вы можете выполнить параллель для цикла и ожидать его завершения в одном вызове), но если у вас нет особых потребностей, это, вероятно, не так уж и важно.