iOS. Приемы программирования
Шрифт:
Мы определяем целочисленную локальную переменную и сначала присваиваем ей значение 10. Затем реализуем блоковый объект, но пока не вызываем его. После того как блоковый объект реализован, мы просто изменяем значение локальной переменной, которую затем (после того как мы его вызовем) попытается считать блоковый объект. Сразу после изменения значения
Вот что здесь происходит. Блоковый объект сохраняет для себя копию переменной integerValue, доступную только для чтения, и делает это именно там, где реализуется блок. Напрашивается вопрос: почему же блоковый объект принимает доступное только для чтения значение переменной integerValue? Ответ прост, и мы уже дали его в этом разделе. Если у локальной переменной нет префикса __block, означающего соответствующий тип хранения, локальные переменные в лексической области видимости блокового объекта просто передаются блоковому объекту как переменные, доступные только для чтения. Следовательно, чтобы изменить это поведение, мы могли бы изменить реализацию метода scopeTest и сопроводить переменную integerValue префиксом __block, указывающим тип хранения. Это делается так:
Теперь, если вывести на консоль результаты после вызова метода scopeTest, мы увидим следующее:
Итак, в данном разделе мы довольно подробно рассмотрели вопросы использования переменных с блоковыми объектами. Рекомендую вам написать несколько блоковых объектов и попытаться использовать в них переменные. Присваивайте им переменные, считывайте из них информацию, чтобы лучше разобраться с тем, как в блоковых объектах применяются переменные. Перечитайте этот раздел, если случайно забудете правила, регулирующие доступ к переменным в блоковых объектах.
7.3. Вызов блоковых объектов
Постановка задачи
Вы научились создавать блоковые объекты, а теперь требуется их исполнять и получать определенные результаты.
Решение
Исполняйте ваши блоковые объекты так же, как и функции на языке C. Подробнее об этом — в подразделе
Обсуждение
В разделах 7.1 и 7.2 вы видели примеры вызова блоковых объектов. В данном разделе приводятся более конкретные примеры.
Если у вас есть независимый блоковый объект, его можно вызвать так же, как мы вызывали бы функцию на языке C:
Если вы хотите вызвать независимый блоковый объект внутри другого независимого блокового объекта, действуйте так же, как при активизации метода на языке C:
Продолжим данный пример и вызовем метод callTrimBlock на языке Objective-C:
Метод callTrimBlock вызовет блоковый объект trimWithOtherBlock, а этот объект вызовет блоковый объект trimString, чтобы обрезать указанную строку. Отсечение строки — простая операция, для ее выполнения требуется всего одна строка кода. Но этот пример демонстрирует, как можно вызывать блоковые объекты внутри блоковых объектов.
См. также
Разделы 7.1 и 7.2.
7.4. Решение с помощью GCD задач, связанных с пользовательским интерфейсом
Постановка задачи
Интерфейс программирования приложений GCD используется для параллельного программирования, и необходимо узнать, каков оптимальный способ его применения с другими API, связанными с пользовательским интерфейсом.
Решение
Воспользуйтесь функцией dispatch_get_main_queue.
Обсуждение
Задачи, связанные с пользовательским интерфейсом, должны выполняться в главном потоке. Поэтому единственным каналом для передачи в GCD задач, связанных с пользовательским интерфейсом, и их выполнения оказывается главная очередь. В качестве описателя главной диспетчерской очереди можно применять функцию dispatch_get_main_queue.
Существует два способа направления задач в основную очередь. Оба этих способа асинхронны и позволяют не прерывать исполнения программы на время, пока завершается операция: