Читаем iOS. Приемы программирования полностью

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), и как при необходимости смешивать создаваемый код с кодом пользовательского интерфейса.

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

Постановка задачи

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

Решение

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

Обсуждение

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

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже