Чтение онлайн

на главную - закладки

Жанры

iOS. Приемы программирования

Нахавандипур Вандад

Шрифт:

myBlock;

NSLog(@"Integer value outside the block = %lu",

(unsigned long)integerValue);

}

Мы определяем целочисленную локальную переменную и сначала присваиваем ей значение 10. Затем реализуем блоковый объект, но пока не вызываем его. После того как блоковый объект реализован, мы просто изменяем значение локальной переменной, которую затем (после того как мы его вызовем) попытается считать блоковый объект. Сразу после изменения значения

локальной переменной на 20 вызываем блоковый объект. Логично предположить, что блоковый объект выведет для переменной на консоль значение 20, но этого не произойдет. Он выведет значение 10, как показано здесь:

Integer value inside the block = 10

Integer value outside the block = 20

Вот что здесь происходит. Блоковый объект сохраняет для себя копию переменной integerValue, доступную только для чтения, и делает это именно там, где реализуется блок. Напрашивается вопрос: почему же блоковый объект принимает доступное только для чтения значение переменной integerValue? Ответ прост, и мы уже дали его в этом разделе. Если у локальной переменной нет префикса __block, означающего соответствующий тип хранения, локальные переменные в лексической области видимости блокового объекта просто передаются блоковому объекту как переменные, доступные только для чтения. Следовательно, чтобы изменить это поведение, мы могли бы изменить реализацию метода scopeTest и сопроводить переменную integerValue префиксом __block, указывающим тип хранения. Это делается так:

— (void) scopeTest{

__block NSUInteger integerValue = 10;

BlockWithNoParams myBlock = ^{

NSLog(@"Integer value inside the block = %lu",

(unsigned long)integerValue);

};

integerValue = 20;

/* Вызываем блок здесь после изменения

значения переменной integerValue. */

myBlock;

NSLog(@"Integer value outside the block = %lu",

(unsigned long)integerValue);

}

Теперь, если вывести на консоль результаты после вызова метода scopeTest, мы увидим следующее:

Integer value inside the block = 20

Integer value outside the block = 20

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

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.

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

Поделиться:
Популярные книги

Война

Валериев Игорь
7. Ермак
Фантастика:
боевая фантастика
альтернативная история
5.25
рейтинг книги
Война

Экономка тайного советника

Семина Дия
Фантастика:
фэнтези
5.00
рейтинг книги
Экономка тайного советника

Чужбина

Седой Василий
2. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чужбина

Мятежник

Прокофьев Роман Юрьевич
4. Стеллар
Фантастика:
боевая фантастика
7.39
рейтинг книги
Мятежник

Бестужев. Служба Государевой Безопасности. Книга вторая

Измайлов Сергей
2. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга вторая

Метатель. Книга 3

Тарасов Ник
3. Метатель
Фантастика:
попаданцы
альтернативная история
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель. Книга 3

Студент из прошлого тысячелетия

Еслер Андрей
2. Соприкосновение миров
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Студент из прошлого тысячелетия

Ты не мой BOY

Рам Янка
5. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Ты не мой BOY

Идеальный мир для Лекаря 2

Сапфир Олег
2. Лекарь
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 2

Лекарь для захватчика

Романова Елена
Фантастика:
попаданцы
историческое фэнтези
фэнтези
5.00
рейтинг книги
Лекарь для захватчика

Отверженный VI: Эльфийский Петербург

Опсокополос Алексис
6. Отверженный
Фантастика:
городское фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Отверженный VI: Эльфийский Петербург

Он тебя не любит(?)

Тоцка Тала
Любовные романы:
современные любовные романы
7.46
рейтинг книги
Он тебя не любит(?)

Убивать чтобы жить 3

Бор Жорж
3. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 3

Темный Лекарь 11

Токсик Саша
11. Темный Лекарь
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Темный Лекарь 11