Вандад Нахавандипур - iOS. Приемы программирования
- Название:iOS. Приемы программирования
- Автор:
- Жанр:
- Издательство:Питер
- Год:2014
- Город:Санкт-Петербург
- ISBN:978-5-496-01016-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Вандад Нахавандипур - iOS. Приемы программирования краткое содержание
Книга, которую вы держите в руках, представляет собой новый, полностью переписанный сборник приемов программирования по работе с iOS. Он поможет вам справиться с наболевшими проблемами, с которыми приходится сталкиваться при разработке приложений для iPhone, iPad и iPod Touch. Вы быстро освоите всю информацию, необходимую для начала работы с iOS 7 SDK, в частности познакомитесь с решениями для добавления в ваши приложения реалистичной физики или движений — в этом вам помогут API UIKit Dynamics.
Вы изучите новые многочисленные способы хранения и защиты данных, отправки и получения уведомлений, улучшения и анимации графики, управления файлами и каталогами, а также рассмотрите многие другие темы. При описании каждого приема программирования приводятся образцы кода, которые вы можете смело использовать.
iOS. Приемы программирования - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
[self isCancelled] == NO){
/* Здесь выполняется задача. */
NSLog(@"Main Thread = %@", [NSThread mainThread]);
NSLog(@"Current Thread = %@", [NSThread currentThread]);
NSUInteger counter = startingCount;
for (counter = startingCount;
counter < endingCount;
counter++){
NSLog(@"Count = %lu", (unsigned long)counter);
}
/* Очень важно. Здесь мы можем выйти из цикла, по-прежнему
соблюдая правила, по которым отменяются операции. */
taskIsFinished = YES;
}
/* Соответствие KVO. Генерируем требуемые уведомления KVO. */
[self willChangeValueForKey:@"isFinished"];
[self willChangeValueForKey:@"isExecuting"];
finished = YES;
executing = NO;
[self didChangeValueForKey:@"isFinished"];
[self didChangeValueForKey:@"isExecuting"];
}
}
@catch (NSException * e) {
NSLog(@"Exception %@", e);
}
}
@end
Операцию можно начать так:
@interface AppDelegate ()
@property (nonatomic, strong) CountingOperation *simpleOperation;
@end
@implementation AppDelegate
— (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
self.simpleOperation = [[CountingOperation alloc] initWithStartingCount:0
endingCount:1000];
[self.simpleOperation start];
NSLog(@"Main thread is here");
self.window = [[UIWindow alloc] initWithFrame:
[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
@end
Запустив данный код, мы увидим в окне консоли следующие результаты, точно как при применении блоковой операции:
Main Thread = {name = (null), num = 1}
Current Thread = {name = (null), num = 1}
…
Count = 993
Count = 994
Count = 995
Count = 996
Count = 997
Count = 998
Count = 999
Main thread is here
См. также
Раздел 7.12.
7.12. Асинхронное выполнение задач с помощью операций
Постановка задачи
Требуется параллельно выполнять операции.
Решение
Воспользуйтесь операционными очередями. В качестве альтернативы можно создавать подклассы от NSOperation и откреплять новый поток в методе main.
Обсуждение
Как говорилось в разделе 7.11, операции по умолчанию работают в том потоке, который вызывает метод start. Обычно операции запускаются в основном потоке, но в то же время мы ожидаем, что операции будут выполняться в собственных потоках и, соответственно, не будут тратить процессорное время, уделяемое главному потоку. Наилучшим решением для обеспечения такой работы будет применение операционных очередей. Однако если вы хотите управлять своими операциями вручную, чего бы я не рекомендовал, то можно было бы создавать подклассы от NSOperation и откреплять новый поток в главном методе. Подробнее об открепленных потоках поговорим в разделе 7.15.
Идем дальше. Попробуем воспользоваться операционной очередью и добавим к ней две простые инициирующие операции (подробнее об инициирующих операциях рассказано в разделе 7.0). Дополнительные примеры кода, описывающие инициирующие операции, имеются в разделе 7.11. Вот объявление (.hm-файл) делегата приложения, в котором используются операционная очередь и две инициирующие операции:
@interface AppDelegate ()
@property (nonatomic, strong) NSOperationQueue *operationQueue;
@property (nonatomic, strong) NSInvocationOperation *firstOperation;
@property (nonatomic, strong) NSInvocationOperation *secondOperation;
@end
@implementation AppDelegate
А вот и внутренняя часть файла реализации делегата приложения:
— (void) firstOperationEntry:(id)paramObject{
NSLog(@"%s", __FUNCTION__);
NSLog(@"Parameter Object = %@", paramObject);
NSLog(@"Main Thread = %@", [NSThread mainThread]);
NSLog(@"Current Thread = %@", [NSThread currentThread]);
}
— (void) secondOperationEntry:(id)paramObject{
NSLog(@"%s", __FUNCTION__);
NSLog(@"Parameter Object = %@", paramObject);
NSLog(@"Main Thread = %@", [NSThread mainThread]);
NSLog(@"Current Thread = %@", [NSThread currentThread]);
}
— (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSNumber *firstNumber = @111;
NSNumber *secondNumber = @222;
self.firstOperation =[[NSInvocationOperation alloc]
initWithTarget: self
selector:@selector(firstOperationEntry:)
object: firstNumber];
self.secondOperation = [[NSInvocationOperation alloc]
initWithTarget: self
selector:@selector(secondOperationEntry:)
object: secondNumber];
self.operationQueue = [[NSOperationQueue alloc] init];
/* Добавляем операции в очередь. */
[self.operationQueue addOperation: self.firstOperation];
[self.operationQueue addOperation: self.secondOperation];
NSLog(@"Main thread is here");
self.window = [[UIWindow alloc] initWithFrame:
[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Вот что происходит в реализации данного кода.
У нас есть два метода, firstOperationEntry: и secondOperationEntry:. Каждый из этих методов принимает в качестве параметра объект и выводит в окне консоли информацию об актуальном потоке, главном потоке и этом параметре. Это входные методы инициирующих операций, которые будут добавляться в операционную очередь.
Мы инициализируем два метода типа NSInvocationOperation и задаем целевой селектор в точке входа каждой операции (эти точки входа были описаны выше).
Затем инициализируем объект типа NSOperationQueue. (Он может создаваться и до того, как созданы методы входа.) Объект очереди будет обеспечивать параллелизм в работе операционных объектов. На данном этапе операционная очередь может немедленно начать (а может и не начать) запускать инициирующие операции, пользуясь их методами start. При этом очень важно помнить, что после добавления операции в операционную очередь от вас не требуется запускать операции вручную. Обеспечением запуска занимается операционная очередь.
Итак, еще раз запустим код примера и посмотрим, что же у нас на консоли:
[Running_Tasks_Asynchronously_with_OperationsAppDelegate firstOperationEntry: ]
Main thread is here
Parameter Object = 111
[Running_Tasks_Asynchronously_with_OperationsAppDelegate secondOperationEntry: ]
Main Thread = {name = (null), num = 1}
Parameter Object = 222
Current Thread = {name = (null), num = 3}
Main Thread = {name = (null), num = 1}
Current Thread = {name = (null), num = 4}
Блестяще! Это доказывает, что инициирующие операции параллельно выполняются каждая в своем потоке и в то же время параллельно главному потоку, вообще не блокируя его. Теперь еще пару раз прогоним этот же код и посмотрим, какой вывод будет появляться в окне консоли. В таком случае вы можете получить совершенно иной результат, например:
Main thread is here
[Running_Tasks_Asynchronously_with_OperationsAppDelegate firstOperationEntry: ]
[Running_Tasks_Asynchronously_with_OperationsAppDelegate secondOperationEntry: ]
Parameter Object = 111
Main Thread = {name = (null), num = 1}
Current Thread = {name = (null), num = 3}
Parameter Object = 222
Main Thread = {name = (null), num = 1}
Current Thread = {name = (null), num = 4}
Очевидно, что главный поток не блокируется и что обе инициирующие операции работают параллельно с главным потоком. Это доказывает, что в операционной очереди сохраняется параллелизм даже тогда, когда в нее добавляются две непараллельные операции. Операционная очередь управляет потоками, необходимыми для осуществления операций.
Читать дальшеИнтервал:
Закладка: