Чтение онлайн

ЖАНРЫ

iOS. Приемы программирования

Нахавандипур Вандад

Шрифт:

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 = <NSThread: 0x68 10260>{name = (null), num = 1}

Current Thread = <NSThread: 0x68 10260>{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 = <NSThread: 0x68 10260>{name = (null), num = 1}

Parameter Object = 222

Поделиться с друзьями: