dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^(void) {
[[[UIAlertView alloc] initWithTitle:@"GCD"
message:@"GCD is amazing!"
delegate: nil
cancelButtonTitle:@"OK"
otherButtonTitles: nil, nil] show];
});
Как видите, функция GCD dispatch_async не имеет ни параметров, ни возвращаемого значения. Блоковый объект, передаваемый данной функции для выполнения задачи, должен самостоятельно собирать данные для этого. В только что рассмотренном примере кода присутствует вид с предупреждением, имеющий все значения, которые требуются ему для выполнения задачи. Но так бывает не всегда. Иногда вам необходимо удостовериться, что блоковый объект, передаваемый GCD, располагает в собственной области видимости всеми значениями, которые требуются для решения стоящей перед ним задачи.
Если запустить данное приложение в эмуляторе iOS, пользователь увидит примерно такую картинку, как на рис. 7.1.
Рис. 7.1. Предупреждение, при выводе которого применялись асинхронные вызовы к GCD.
В общем-то, этот результат не слишком впечатляет. Так благодаря чему же главная очередь так интересна? Ответ прост: когда приходится задействовать GCD на полную мощность, например, чтобы выполнить сложные вычисления в параллельных или последовательных потоках, вам, возможно, понадобится отображать текущие результаты для пользователя или перемещать какой-либо компонент на экране. В таких случаях
Если вы не хотите передавать блоковый объект для выполнения в главную очередь, можно передать объект, представляющий собой функцию на языке C. Передавайте функции dispatch_async_f все те функции C, которые предполагается направлять на выполнение в GCD и которые относятся к работе пользовательского интерфейса. Мы можем получить такие же результаты, как на рис. 7.1, используя вместо блоковых объектов функции на языке C, при этом потребуется внести в код лишь незначительные корректировки.
Как было указано ранее, функция dispatch_async_f позволяет передавать указатель на контекст, определяемый приложением. Этот контекст впоследствии может использоваться вызываемой нами функцией C. Итак, создадим структуру, в которой будут содержаться значения — в частности, заголовок предупреждающего вида, сообщение и надпись Cancel (Отмена) на соответствующей кнопке. Когда приложение запустится, мы поместим в эту структуру все значения и передадим ее функции C для отображения. Вот как определяется эта структура:
typedef struct{
char *title;
char *message;
char *cancelButtonTitle;
} AlertViewData;
Итак, продолжим и реализуем функцию C, которая в дальнейшем будет вызываться с GCD. Эта функция должна ожидать параметр типа void *, тип которого затем приводится к AlertViewData *. Иными словами, мы ожидаем от вызывающей стороны этой функции, что нам будет передана ссылка на данные, необходимые для работы предупреждающего вида, которые инкапсулированы в структуре AlertViewData:
void displayAlertView(void *paramContext){
AlertViewData *alertData = (AlertViewData *)paramContext;
NSString *title =
[NSString stringWithUTF8String: alertData->title];
NSString *message =
[NSString stringWithUTF8String: alertData->message];
NSString *cancelButtonTitle =
[NSString stringWithUTF8String: alertData->cancelButtonTitle];
[[[UIAlertView alloc] initWithTitle: title
message: message
delegate: nil
cancelButtonTitle: cancelButtonTitle