Grand Central Dispatch — пример использования iOS

Давайте создадим пример того, что мы рассматривали в статье  Grand Central Dispatch в iOS на Swift. Очереди

Начнем с создания собственной очереди.

Для создания очереди нам требуется указать имя очереди, что как мы помним облегчит жизнь при отладке iOS приложения. Укажем тип очереди, serieal (по-умолчанию) или concurrent и тип очереди, определяемый QOS.

Имя очереди

Давайте создадим вспомогательную функцию для вывода в консоль имени текущей очереди.

Думаю, тут нет ничего сложного. Единственное, что стоит хорошо понимать, что GCD это набор функций языка программирования C. Поэтому нужно сделать преобразование строки из типа CString в String.

Теперь давайте опробуем в деле нашу новую функцию.

В данном коде в первом варианте мы запросили имя основной очереди, в которой выполняется программа, а во втором случае то же самое мы запросили уже в собственной очереди. Результат в консоли будет выглядеть так:

Собственно, результат вполне предсказуем.

ASYNC vs SYNC

Стоит на примере разобраться чем отличаются функции dispatch_async и dispatch_sync. Для этого будем использовать нашу созданную выше очередь. Этот код мы будем использовать для того, чтобы увидеть начало и окончание передачи задач в очередь, а также момент окончания выполнения задачи.  Строки, которые попадают в консоль и комментарии говорят сами за себя. По коду ниже не должно возникнуть вопросов.

Внимательно посмотрите на результат работы этой части программы:

Хорошо видно, что в  блоке ASYNC консоль отобразила сообщение о начале передачи задачи, об окончании передачи, и лишь потом появилось сообщение о выполнении задачи.

В блоке SYNC напротив все сообщения идут в последовательности действий. Т.е. сначала сообщение о начале передачи задачи, потом выполнение задачи, очередь ждала полного выполнения этой задачи, и только после этого продолжилось выполнение остального кода программы, где вышло сообщение об окончании передачи задачи в очередь.

SERIAL vs CONCURRENT

Для демонстрации работы разного типа очередей создадим функцию hardJob(), в которой будем останавливать поток на одну секунду с помощью функции sleep(1), и после паузы выводить сообщение об окончании работы. Для удобства я также добавил в лог имя очереди и время, которое было затрачено на выполнение задачи. Вывод времени реализуется с помощью функций startClock() — которая запоминает момент времени «сейчас» и showClock(), которая выводит время, прошедшее с момента выполнения  startClock().

В примере выше мы создали очередь типа Serial, поэтому ее мы опробуем первой. Пошлем четыре раза задачу hardJob() в нашу очередь.

Затем в блоке //CONCURRENT мы создадим очередь Concurrent и также пошлем задачу hardJob() во вновь созданную очередь. У меня получилось, что я послал ее пять раз. Но для нашего примера это не принципиально.

Результат работы последней части программы:

Итак, видно, что все задачи в очереди ru.proSwift.primer выполняются последовательно, и на выполнение всех четырех потребовалось 4 секунды. А в очереди  ru.proSwift.concurrent задачи выполнились за секунду, даже с учетом того, что их пять.

И еще момент, внимательный читатель заметит, что строка кода, которая выводит в консоль линию отреза …

… идет после добавления задач в очередь, а при выводе лога в консоль линия отреза выводится сразу после сообщения о передачи задач в очередь. Причем тип очередь никак не влияет на эту ситуацию. Почему так происходит?

Оставляю читателям возможность перечитать эту статью еще раз и поразмышлять об этом в комментариях…

Опубликовано в Iron ribbon, Мультизадачность, Реальные примеры Метки: ,
4 комментария на “Grand Central Dispatch — пример использования iOS
  1. Анатолий:

    Добрый день.
    Пытался организовать синхронную загрузку данных с помощью Alamofire и не получилось.
    Вы не могли бы показать, как это можно сделать?
    Как я понял, основная сложность заключается в том, что в файле Download.swift фреймворка организованы свои механизмы асинхронной загрузки. И как их обойти большой вопрос.
    Мне бы хотелось, чтобы пока грузятся данных из инета отображался прогрессбар и никакие действия в основном интерфейсе не были доступны (т.е. чтобы я, например, не мог перейти на другой вью при нажатии на одном из item’во в таб баре).
    p.s. Если нужен пример того, что я написал, то могу скинуть.

  2. Анатолий:

    Спасибо!!!
    Сейчас посмотрю.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*