otherButtonTitles: nil, nil] show];

free(alertData);

}

Причина, по которой мы применяем free к переданному нам контексту именно здесь, а не на вызывающей стороне, заключается в том, что вызывающая сторона будет выполнять эту функцию C асинхронно и не сможет узнать, когда выполнение функции на языке C завершится. Поэтому вызывающая сторона должна выделить достаточный объем памяти для контекста AlertViewData (операция malloc), и функция C displayAlertView должна высвободить это пространство.

А теперь вызовем функцию displayAlertView применительно к основной очереди и передадим ей контекст (структуру, содержащую данные для предупреждающего вида):

— (BOOL) application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

dispatch_queue_t mainQueue = dispatch_get_main_queue();

AlertViewData *context = (AlertViewData *)

malloc(sizeof(AlertViewData));

if (context!= NULL){

context->title = «GCD»;

context->message = «GCD is amazing.»;

context->cancelButtonTitle = «OK»;

dispatch_async_f(mainQueue,

(void *)context,

displayAlertView);

}

self.window = [[UIWindow alloc] initWithFrame:

[[UIScreen mainScreen] bounds]];

self.window.backgroundColor = [UIColor whiteColor];

[self.window makeKeyAndVisible];

return YES;

}

Если активизировать метод класса currentThread, относящийся к классу NSThread, то выяснится, что блоковые объекты или функции C, направляемые вами в главную очередь, действительно работают в главном потоке:

— (BOOL) application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

dispatch_queue_t mainQueue = dispatch_get_main_queue();

dispatch_async(mainQueue, ^(void) {

NSLog(@"Current thread = %@", [NSThread currentThread]);

NSLog(@"Main thread = %@", [NSThread mainThread]);

});

self.window = [[UIWindow alloc] initWithFrame:

[[UIScreen mainScreen] bounds]];

self.window.backgroundColor = [UIColor whiteColor];

[self.window makeKeyAndVisible];

return YES;

}

Вывод данного кода будет примерно таким:

Current thread = {name = (null), num = 1}

Main thread = {name = (null), num = 1}

Итак, мы изучили, как с помощью GCD решаются задачи, связанные с пользовательским интерфейсом. Перейдем к другим темам — в частности, поговорим о том, как выполнять задачи параллельно, используя параллельные очереди (см. разделы 7.5 и 7.6), и как при необходимости смешивать создаваемый код с кодом пользовательского интерфейса.

<p>7.5. Синхронное решение с помощью GCD задач, не связанных с пользовательским интерфейсом</p><p>Постановка задачи</p>

Необходимо выполнять синхронные задачи, в которых не участвует код, связанный с пользовательским интерфейсом.

<p>Решение</p>

Воспользуйтесь функцией dispatch_sync.

<p>Обсуждение</p>

Иногда необходимо решать задачи, никак не связанные с пользовательским интерфейсом, либо осуществлять процессы, которые взаимодействуют и с пользовательским интерфейсом, но в то же время заняты решением долговременных задач. Например, вам может понадобиться загрузить изображение, а после загрузки отобразить его для пользователя. Процесс загрузки совершенно не связан с пользовательским интерфейсом.

Перейти на страницу:

Все книги серии Бестселлеры O'Reilly

Похожие книги