- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания iOS. Приемы программирования - Вандад Нахавандипур
Шрифт:
Интервал:
Закладка:
• Операции можно отменять. Так, если вы создаете подклассы от NSOperation, чтобы делать собственные виды объектов операций, обязательно пользуйтесь методом экземпляра isCancelled. Он применяется, чтобы проверить, не была ли отменена определенная операция, прежде чем переходить к выполнению задачи, связанной с этой операцией. Например, если задача вашей операции — проверять доступность соединения с Интернетом раз в 20 с, то перед каждым запуском операции нужно вызвать метод экземпляра isCancelled, чтобы сначала убедиться, что операция не отменена, и только после этого пытаться проверять наличие соединения с Интернетом. Если на выполнение операции уходит более нескольких секунд (например, если это загрузка файла), то при выполнении задачи нужно также периодически проверять метод isCancelled.
• Объекты операций обязаны выполнять «уведомление наблюдателей об изменениях в свойствах наблюдаемого объекта» (KVO, Key-Value Observing) на различных ключевых путях, в частности isFinished, isReady и isExecuting. В одной из следующих глав мы обсудим механизм KVO, а также KVC — механизм для доступа к полям объекта по именам этих полей.
• Если вы планируете создавать подкласс от NSOperation и выполнять специальную реализацию для операции, вам следует создать собственный автоматически высвобождаемый пул в методе main, относящемся к операции. Данный метод вызывается из метода start. Эти вопросы мы подробнее рассмотрим далее в этой главе.
• Всегда сохраняйте ссылки на создаваемые вами объекты операций. Сама параллельная природа, присущая очередям операций, исключает возможность получения ссылки на операцию после того, как она добавлена в очередь.
Потоки и таймеры — это объекты, являющиеся подклассами от NSObject. Для порождения потока выполняется больше работы, чем для создания таймеров, а настройка цикла потока — более сложная задача, чем обычное слушание таймера, запускающего селектор. Когда приложение работает в операционной системе iOS, система создает для этого приложения как минимум один поток. Этот поток называется главным (Main Thread). Все потоки и таймеры должны добавляться в цикл исполнения (Run Loop). Цикл исполнения, как понятно из его названия, — это цикл, в ходе которого могут происходить разные события, например запуск таймера или выполнение потока. Обсуждение циклов исполнения выходит за рамки этой главы, но иногда я буду упоминать такой цикл.
Цикл исполнения — это, в сущности, обычный цикл, у которого есть начальная точка, условие завершения и серия событий, которые необходимо обработать в ходе этого цикла. Поток или таймер прикрепляются к циклу исполнения, и, в сущности, именно они заставляют цикл исполнения работать.
Главный поток приложения — это тот поток, который обрабатывает события пользовательского интерфейса. Если вы выполняете в главном потоке долговременную задачу, то быстро станет заметно, что интерфейс перестает отвечать на запросы или реагирует медленно. Во избежание этого можно создавать отдельные потоки и/или таймеры, каждый из которых выполняет собственную задачу (даже если она сравнительно долговременная). Но при этом главный поток не будет блокироваться.
7.1. Создание блоковых объектов
Постановка задачи
Необходимо иметь возможность писать собственные блоковые объекты либо использовать блоковые объекты с классами из iOS SDK.
Решение
Просто необходимо понимать базовую разницу между синтаксисом блоковых объектов и синтаксисом классических функций языка C. Эта разница рассматривается в подразделе «Обсуждение» данного раздела.
Обсуждение
Блоковые объекты могут быть либо встраиваемыми, либо записываемыми как отдельные блоки кода. Начнем с объектов второго типа. Предположим, у нас есть метод языка Objective-C, принимающий два целочисленных значения типа NSInteger и возвращающий разницу двух этих значений в форме NSInteger. Разница получается в результате вычитания одного значения из другого:
— (NSInteger) subtract:(NSInteger)paramValue
from:(NSInteger)paramFrom{
return paramFrom — paramValue;
}
Очень просто, правда? Теперь преобразуем этот код Objective-C в классическую функцию языка C, обеспечивающую такую же функциональность. Это еще на шаг приблизит нас к пониманию синтаксиса блоковых объектов:
NSInteger subtract(NSInteger paramValue, NSInteger paramFrom){
return paramFrom — paramValue;
}
Как видите, синтаксис функции на C значительно отличается от синтаксиса аналогичной функции на языке Objective-C. Теперь рассмотрим, как можно написать ту же функцию в виде блокового объекта:
NSInteger (^subtract)(NSInteger, NSInteger) =
^(NSInteger paramValue, NSInteger paramFrom){
return paramFrom — paramValue;
};
Прежде чем перейти к детальному описанию синтаксиса блоковых объектов, приведу еще несколько примеров. Предположим, что у нас есть функция на языке C, принимающая параметр типа NSUInteger (беззнаковое целое число) и возвращающая строку типа NSString. Вот как данная функция реализуется на C:
NSString* intToString (NSUInteger paramInteger){
return [NSString stringWithFormat:@"%lu",
(unsigned long)paramInteger];
}
Чтобы научиться форматировать строки с применением системонезависимых указателей формата на языке Objective-C, ознакомьтесь с String Programming Guide in the iOS Developer Library (Руководство по программированию строк в библиотеке разработчика iOS). Адрес документа на сайте Apple: https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html.
Блоковый объект, эквивалентный данной функции языка C, показан в примере 7.1.
Пример 7.1. Образец блокового объекта, определенного в виде функции
NSString* (^intToString)(NSUInteger) = ^(NSUInteger paramInteger){
NSString *result = [NSString stringWithFormat:@"%lu",
(unsigned long)paramInteger];
return result;
};
Простейший независимый блоковый объект — это блоковый объект, возвращающий void и не принимающий никаких параметров:
void (^simpleBlock)(void) = ^{
/* Здесь реализуется блоковый объект. */
};
Блоковые объекты инициируются точно так же, как и функции на языке C. Если у них есть какие-либо параметры, то вы передаете их так, как и в функции C. Любое возвращаемое значение можно получить точно так же, как и возвращаемое значение функции на языке C. Вот пример:
NSString* (^intToString)(NSUInteger) = ^(NSUInteger paramInteger){
NSString *result = [NSString stringWithFormat:@"%lu",
(unsigned long)paramInteger];
return result;
};
— (void) callIntToString{
NSString *string = intToString(10);
NSLog(@"string = %@", string);
}
Метод callIntToString языка Objective-C вызывает блоковый объект intToString, передавая этому блоковому объекту в качестве единственного параметра значение 10 и помещая возвращаемое значение данного блокового объекта в локальную переменную string.
Теперь, когда мы знаем, как писать блоковые объекты в виде независимых блоков кода, рассмотрим передачу блоковых объектов как передачу параметров методам языка Objective-C. Чтобы понять смысл следующего примера, нужно прибегнуть к определенным абстракциям.
Предположим, у нас есть метод Objective-C, принимающий целое число и выполняющий над ним какое-либо преобразование. Такое преобразование может меняться в зависимости от того, что еще происходит в программе. Мы уже знаем, что у нас будет целое число в качестве ввода и строка в качестве вывода, но сам процесс преобразования поручим блоковому объекту — а этот объект может быть иным при каждом вызове метода. Следовательно, в качестве параметров данный метод будет принимать и целое число, которое необходимо преобразовать, и тот блок, который будет выполнять преобразование.
Для блокового объекта воспользуемся тем же блоковым объектом intToString, который мы реализовали в примере 7.1. Теперь нам нужен метод на языке Objective-C, который будет принимать в качестве параметра беззнаковое целое число, а в качестве еще одного параметра — блоковый объект. С беззнаковым целым в качестве параметра все просто, но как сообщить методу, что он должен принимать блоковый объект того же типа, к которому относится блоковый объект intToString? Сначала определяем псевдоним сигнатуры блокового объекта intToString (с помощью ключевого слова typedef) и таким образом сообщаем компилятору, какие параметры должен принимать блоковый объект:
typedef NSString* (^IntToStringConverter)(NSUInteger paramInteger);
Объявление typedef просто сообщает компилятору, что блоковые объекты, принимающие в качестве параметра целое число и возвращающие строку, можно представлять с помощью обычного идентификатора, называемого IntToStringConverter. Итак, пойдем дальше и напишем метод на Objective-C, который будет принимать в качестве параметров и целое число, и блоковый объект типа IntToStringConverter: