Вандад Нахавандипур - iOS. Приемы программирования
- Название:iOS. Приемы программирования
- Автор:
- Жанр:
- Издательство:Питер
- Год:2014
- Город:Санкт-Петербург
- ISBN:978-5-496-01016-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Вандад Нахавандипур - iOS. Приемы программирования краткое содержание
Книга, которую вы держите в руках, представляет собой новый, полностью переписанный сборник приемов программирования по работе с iOS. Он поможет вам справиться с наболевшими проблемами, с которыми приходится сталкиваться при разработке приложений для iPhone, iPad и iPod Touch. Вы быстро освоите всю информацию, необходимую для начала работы с iOS 7 SDK, в частности познакомитесь с решениями для добавления в ваши приложения реалистичной физики или движений — в этом вам помогут API UIKit Dynamics.
Вы изучите новые многочисленные способы хранения и защиты данных, отправки и получения уведомлений, улучшения и анимации графики, управления файлами и каталогами, а также рассмотрите многие другие темы. При описании каждого приема программирования приводятся образцы кода, которые вы можете смело использовать.
iOS. Приемы программирования - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Пример 7.3. Блоковый объект, определенный в виде функции
— (void) doTheConversion{
IntToStringConverter inlineConverter = ^(NSUInteger paramInteger){
NSString *result = [NSString stringWithFormat:@"%lu",
(unsigned long)paramInteger];
return result;
};
NSString *result = [self convertIntToString:123
usingBlockObject: inlineConverter];
NSLog(@"result = %@", result);
}
Сравните примеры 7.1 и 7.3. Я удалил имевшийся в первом варианте код, в котором мы формировали сигнатуру блокового объекта. Данная сигнатура состояла из имени и аргумента — (^intToString) (NSUInteger). Остальную часть блокового объекта я не трогаю, и теперь он становится анонимным объектом. Но это не означает, что я никак не могу сослаться на блоковый объект. С помощью знака равенства (=) я присваиваю блоковый объект типу и имени: IntToStringConverter inlineConverter. Теперь я могу воспользоваться типом данных, чтобы стимулировать правильную работу методов, а при самой операции передачи блокового объекта использовать его имя.
Кроме того способа создания встраиваемых блоковых объектов, который только что был продемонстрирован, существует способ создания блокового объекта на этапе передачи его как параметра:
— (void) doTheConversion{
NSString *result =
[self convertIntToString:123
usingBlockObject: ^NSString *(NSUInteger paramInteger) {
NSString *result = [NSString stringWithFormat:@"%lu",
(unsigned long)paramInteger];
return result;
}];
NSLog(@"result = %@", result);
}
Сравните этот пример с примером 7.2. Оба метода используют блоковый объект с применением синтаксиса usingBlockObject. Но, в то время как при применении первого варианта мы ссылались по имени на предварительно определенный блоковый объект (intToString), во втором варианте блоковый объект создается на лету. В этом коде мы создали встраиваемый блоковый объект, который передается методу convertIntToString: usingBlockObject: как второй параметр.
7.2. Доступ к переменным в блоковых объектах
Постановка задачи
Необходимо понять разницу между доступом к переменным в методах Objective-C и доступом к этим переменным в блоковых объектах.
Решение
Вот краткое обобщение того, что необходимо знать о переменных в блоковых объектах.
Локальные переменные в блоковых объектах работают точно так же, как и в методах Objective-C.
• При работе со встраиваемыми блоковыми объектами к локальным относятся не только те переменные, которые определены внутри блока, но и те, что определены в методе, реализующем данный блоковый объект (чуть позже рассмотрим примеры).
• Нельзя ссылаться на self в независимых блоковых объектах, реализованных в классе Objective-C. Если необходим доступ к self, то вам нужно передать его объект блоковому объекту в качестве параметра. Чуть позже рассмотрим на примере и такую ситуацию.
• Во встраиваемом блоковом объекте на self можно ссылаться лишь в тех случаях, когда self присутствует в лексической области видимости, в рамках которой и создается блоковый объект.
• При работе со встраиваемыми блоковыми объектами локальные переменные, определяемые внутри реализации блокового объекта, доступны для считывания, но не для записи. Однако есть и исключение. Блоковый объект может записывать информацию в такие переменные, если они определены с типом хранения __block. Пример мы также рассмотрим.
• Предположим, у вас есть блоковый объект типа NSObject, а внутри реализации этого объекта вы используете блоковый объект с GCD. Внутри данного блокового объекта у вас будет доступ для чтения и записи к объявленным свойствам того NSObject, внутри которого реализован блок.
• Вы можете получать доступ к объявленным свойствам NSObject внутри независимых блоковых объектов, только если вы работаете с методами-установщиками и методами-получателями этих свойств. Вы не сможете получить доступ к объявленным свойствам объекта внутри независимого блокового объекта с помощью точечной нотации.
Обсуждение
Сначала научимся работать с переменными, которые являются локальными для реализаций двух блоковых объектов. Один из этих блоковых объектов будет встраиваемым, а другой — независимым:
void (^independentBlockObject)(void) = ^(void){
NSInteger localInteger = 10;
NSLog(@"local integer = %ld", (long)localInteger);
localInteger = 20;
NSLog(@"local integer = %ld", (long)localInteger);
};
При активизации этого блокового объекта те значения, которые мы присваиваем, выводятся в окне консоли:
local integer = 10
local integer = 20
Пока все несложно. Теперь рассмотрим встраиваемые блоковые объекты и переменные, которые являются для них локальными:
— (void) simpleMethod{
NSUInteger outsideVariable = 10;
NSMutableArray *array = [[NSMutableArray alloc]
initWithObjects:@"obj1",
@"obj2", nil];
[array sortUsingComparator: ^NSComparisonResult(id obj1, id obj2) {
NSUInteger insideVariable = 20;
NSLog(@"Outside variable = %lu", (unsigned long)outsideVariable);
NSLog(@"Inside variable = %lu", (unsigned long)insideVariable);
/* Возвращаем значение для блокового объекта. */
return NSOrderedSame;
}];
}
Метод экземпляра sortUsingComparator:, относящийся к классу NSMutableArray, пытается сортировать изменяемый массив. Цель кода, приведенного в данном примере, — просто продемонстрировать использование локальных переменных. Можно и не задаваться тем, что именно делает этот метод.
Блоковый объект может считывать информацию и записывать данные в собственную локальную переменную insideVariable. При этом по умолчанию блоковый объект имеет доступ только для чтения к переменной outsideVariable. Чтобы блоковый объект мог записывать информацию в outsideVariable, нужно поставить перед outsideVariable префикс __block, указывающий соответствующий тип хранения:
— (void) simpleMethod{
__block NSUInteger outsideVariable = 10;
NSMutableArray *array = [[NSMutableArray alloc]
initWithObjects:@"obj1",
@"obj2", nil];
[array sortUsingComparator: ^NSComparisonResult(id obj1, id obj2) {
NSUInteger insideVariable = 20;
outsideVariable = 30;
NSLog(@"Outside variable = %lu", (unsigned long)outsideVariable);
NSLog(@"Inside variable = %lu", (unsigned long)insideVariable);
/* Возвращаем значение для блокового объекта. */
return NSOrderedSame;
}];
}
Доступ к self во встраиваемых блоковых объектах не вызывает никаких проблем, пока self определяется в лексической области видимости, внутри которой создается встраиваемый блоковый объект. Например, в данной ситуации блоковый объект сможет получить доступ к self, поскольку метод simpleMethod является методом экземпляра класса языка Objective-C:
— (void) simpleMethod{
NSMutableArray *array = [[NSMutableArray alloc]
initWithObjects:@"obj1",
@"obj2", nil];
[array sortUsingComparator: ^NSComparisonResult(id obj1, id obj2) {
NSLog(@"self = %@", self);
/* Возвращаем значение для блокового объекта. */
return NSOrderedSame;
}];
}
Не внеся изменений в реализацию вашего блокового объекта, вы не сможете получить доступ к self в независимом блоковом объекте. При попытке скомпилировать данный код мы получим ошибку времени компиляции:
Читать дальшеИнтервал:
Закладка: