Интернет магазин китайских планшетных компьютеров |
|
Компьютеры - Grand Central Dispatch - Примеры13 мая 2011Оглавление: 1. Grand Central Dispatch 2. Особенности платформы 3. Примеры Два примера демонстрирующие простоту использования Grand Central Dispatch могут быть найдены в обзоре Snow Leopard Джона Сиракуза на Ars Technica.. Асинхронный вызовИзначально, у нас имеется приложение с методом analyzeDocument, осуществляющим подсчет слов и параграфов в документе. Обычно, процесс подсчета слов и параграфов достаточно быстр и может быть выполнен в главном потоке, без опасений, что пользователь заметит задержку между нажатием кнопки и получением результата: - analyseDocument:sender { NSDictionary *stats = ; ; ; ; } Если документ очень большой, то анализ может занять достаточно много времени, чтобы пользователь заметил «подвисание» приложения. Следующий пример позволяет легко решить эту проблему: - analyzeDocument:sender { dispatch_async, ^{ NSDictionary *stats = ; dispatch_async, ^{ ; ; ; }); }); } Здесь вызов помещен в блок, который затем помещается в одну из глобальных очередей. После того, как завершает работу, новый блок помещается в главную очередь, который обновляет интерфейс пользователя. Проведя эти несложные изменения, программист избежал потенциального «подвисания» приложения при анализе больших документов. Распараллеливание циклаВторой пример демонстрирует распараллеливание цикла: for { results = do_work; } total = summarize; Здесь вызывается функция do_work count раз, результат ее i-го выполнения присваивается i-му элементу массива results, затем результаты суммируются. Нет оснований полагать, что do_works полагается на результаты ее предыдущих вызовов, поэтому ничто не мешает делать несколько вызовов do_works параллельно. Следующий листинг демонстрирует реализацию этой идеи с помощью GCD: dispatch_apply, ^{ results = do_work; }); total = summarize; В этом примере dispatch_apply запускает count раз блок, переданный ему, помещая каждый вызов в глобальную очередь и передавая блокам числа от 0 до count-1. Это позволяет ОС выбрать оптимальное число потоков для наиболее полного использования доступных аппаратных ресурсов. dispatch_apply не возвращает управление, пока все его блоки не завершили работу, это позволяет гарантировать, что перед вызовом summarize вся работа изначального цикла выполнена. Создание последовательных очередейРазработчик может создать отдельную последовательную очередь для задач, которые должны выполняться последовательно, но могут работать в отдельном потоке. Новая очередь может быть создана таким образом: dispatch_queue_t exampleQueue; exampleQueue = dispatch_queue_create; // exampleQueue может быть использована здесь. dispatch_release; Избегайте помещение такой задачи в последовательную очередь, которая помещает другую задачу в ту же самую очередь. Это гарантированно приведет к взаимоблокировке. В следующем листинге продемонстрирован случай такой взаимоблокировки: dispatch_queue_t exampleQueue = dispatch_queue_create; dispatch_sync( exampleQueue, ^{ dispatch_sync( exampleQueue, ^{ printf; }); }); dispatch_release; Просмотров: 2596
|