Итак, в данном разделе мы довольно подробно рассмотрели вопросы использования переменных с блоковыми объектами. Рекомендую вам написать несколько блоковых объектов и попытаться использовать в них переменные. Присваивайте им переменные, считывайте из них информацию, чтобы лучше разобраться с тем, как в блоковых объектах применяются переменные. Перечитайте этот раздел, если случайно забудете правила, регулирующие доступ к переменным в блоковых объектах.
7.3. Вызов блоковых объектов
Постановка задачи
Вы научились создавать блоковые объекты, а теперь требуется их исполнять и получать определенные результаты.
Решение
Исполняйте ваши блоковые объекты так же, как и функции на языке C. Подробнее об этом — в подразделе «Обсуждение».
Обсуждение
В разделах 7.1 и 7.2 вы видели примеры вызова блоковых объектов. В данном разделе приводятся более конкретные примеры.
Если у вас есть независимый блоковый объект, его можно вызвать так же, как мы вызывали бы функцию на языке C:
void (^simpleBlock)(NSString *) = ^(NSString *paramString){
/* Реализуем блоковый объект и используем параметр paramString. */
};
— (void) callSimpleBlock{
simpleBlock(@"O'Reilly");
}
Если вы хотите вызвать независимый блоковый объект внутри другого независимого блокового объекта, действуйте так же, как при активизации метода на языке C:
NSString *(^trimString)(NSString *) = ^(NSString *inputString){
NSString *result = [inputString stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceCharacterSet]];
return result;
};
NSString *(^trimWithOtherBlock)(NSString *) = ^(NSString *inputString){
return trimString(inputString);
};
— (void) callTrimBlock{
NSString *trimmedString = trimWithOtherBlock(@" O'Reilly ");
NSLog(@"Trimmed string = %@", trimmedString);
}
Продолжим данный пример и вызовем метод callTrimBlock на языке Objective-C:
[self callTrimBlock];
Метод callTrimBlock вызовет блоковый объект trimWithOtherBlock, а этот объект вызовет блоковый объект trimString, чтобы обрезать указанную строку. Отсечение строки — простая операция, для ее выполнения требуется всего одна строка кода. Но этот пример демонстрирует, как можно вызывать блоковые объекты внутри блоковых объектов.
См. также
Разделы 7.1 и 7.2.
7.4. Решение с помощью GCD задач, связанных с пользовательским интерфейсом
Постановка задачи
Интерфейс программирования приложений GCD используется для параллельного программирования, и необходимо узнать, каков оптимальный способ его применения с другими API, связанными с пользовательским интерфейсом.
Решение
Воспользуйтесь функцией dispatch_get_main_queue.
Обсуждение
Задачи, связанные с пользовательским интерфейсом, должны выполняться в главном потоке. Поэтому единственным каналом для передачи в GCD задач, связанных с пользовательским интерфейсом, и их выполнения оказывается главная очередь. В качестве описателя главной диспетчерской очереди можно применять функцию dispatch_get_main_queue.
Существует два способа направления задач в основную очередь. Оба этих способа асинхронны и позволяют не прерывать исполнения программы на время, пока завершается операция:
Метод dispatch_sync нельзя применять к главной очереди, поскольку он заблокирует поток на неопределенное время и ваше приложение войдет во взаимную блокировку. Все задачи, направляемые в GCD через главную очередь, должны туда направляться асинхронно.
Рассмотрим использование функции dispatch_async, которая принимает два параметра:
Рассмотрим пример. В операционной системе iOS следующий код будет выводить пользователю предупреждение, и при этом будет применяться главная очередь: