/* Создаем здесь цикл while, существующий лишь в том случае,

когда переменная taskIsFinished устанавливается в YES

или операция отменяется. */

while (taskIsFinished == NO &&

[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

<p>См. также</p>

Раздел 7.12.

<p>7.12. Асинхронное выполнение задач с помощью операций</p><p>Постановка задачи</p>

Требуется параллельно выполнять операции.

<p>Решение</p>

Воспользуйтесь операционными очередями. В качестве альтернативы можно создавать подклассы от NSOperation и откреплять новый поток в методе main.

<p>Обсуждение</p>

Как говорилось в разделе 7.11, операции по умолчанию работают в том потоке, который вызывает метод start. Обычно операции запускаются в основном потоке, но в то же время мы ожидаем, что операции будут выполняться в собственных потоках и, соответственно, не будут тратить процессорное время, уделяемое главному потоку. Наилучшим решением для обеспечения такой работы будет применение операционных очередей. Однако если вы хотите управлять своими операциями вручную, чего бы я не рекомендовал, то можно было бы создавать подклассы от NSOperation и откреплять новый поток в главном методе. Подробнее об открепленных потоках поговорим в разделе 7.15.

Идем дальше. Попробуем воспользоваться операционной очередью и добавим к ней две простые инициирующие операции (подробнее об инициирующих операциях рассказано в разделе 7.0). Дополнительные примеры кода, описывающие инициирующие операции, имеются в разделе 7.11. Вот объявление (.hm-файл) делегата приложения, в котором используются операционная очередь и две инициирующие операции:

@interface AppDelegate ()

Перейти на страницу:

Все книги серии Бестселлеры O'Reilly

Похожие книги