ios-07_2 multithreading

22
iOS Internship 2014 Асинхронность

Upload: noveo

Post on 20-Jun-2015

210 views

Category:

Software


0 download

DESCRIPTION

Noveo iOS school. Lecture 7.

TRANSCRIPT

Page 1: iOS-07_2 Multithreading

iOS Internship 2014Асинхронность

Page 2: iOS-07_2 Multithreading

Асинхронность

NSThreadNSOperation

Grand Central Dispatch

Page 3: iOS-07_2 Multithreading

Асинхронность

● Все долгие операции нужно выполнять не в главном потоке● Все операции с UI нужно выполнять в главном потоке● Нельзя обращаться к одному (изменяемому) объекту из разных потоков "одновременно"● Результат работы не должен зависеть от порядка выполнения асинхронных операций● Распараллеливание независимых операций может ускорить работу программы

Асинхронность в iOS

Page 4: iOS-07_2 Multithreading

Асинхронность

● NSThread○ Используется для длительных (или бесконечных) задач○ Явное создание потока (нужно использовать с умом)

● NSOperation○ Используется для логически обособленных задач○ Потоки создаются автоматически (например по количеству ядер процессора)○ Поддержка отмены операций○ Поддержка графа зависимостей между операциями○ Поддержка приоритезации операций

● GCD○ Лучшая производительность○ Относительно низкоуровневое C API○ Для простых задач — короткая запись○ Используется для быстрого перехода между главным и фоновым потоками

Асинхронность в iOS

Page 5: iOS-07_2 Multithreading

Асинхронность

● NSThread○ Используется для длительных (или бесконечных) задач○ Явное создание потока (нужно использовать с умом)

● NSOperation○ Используется для логически обособленных задач○ Потоки создаются автоматически (например по количеству ядер процессора)○ Поддержка отмены операций○ Поддержка графа зависимостей между операциями○ Поддержка приоритезации операций

● GCD○ Лучшая производительность○ Относительно низкоуровневое C API○ Для простых задач — короткая запись○ Используется для быстрого перехода между главным и фоновым потоками

Асинхронность в iOS

Page 6: iOS-07_2 Multithreading

Асинхронность

● Исполняем уже имеющийся метод в отдельном потоке:NSThread *thread = [[NSThread alloc]

initWithTarget:selfselector:@selector(xxx)object:nil];

[thread start];

● Создаём подкласс NSThread , переопределяем метод main, у экземпляра класса вызываем start.

NSThread

Page 7: iOS-07_2 Multithreading

Асинхронность

● NSThread○ Используется для длительных (или бесконечных) задач○ Явное создание потока (нужно использовать с умом)

● NSOperation○ Используется для логически обособленных задач○ Потоки создаются автоматически (например по количеству ядер процессора)○ Поддержка отмены операций○ Поддержка графа зависимостей между операциями○ Поддержка приоритезации операций

● GCD○ Лучшая производительность○ Относительно низкоуровневое C API○ Для простых задач — короткая запись○ Используется для быстрого перехода между главным и фоновым потоками

Асинхронность в iOS

Page 8: iOS-07_2 Multithreading

Асинхронность

NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{//...

}];

NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{//...

}];

NSOperationQueue *queue = [[NSOperationQueue alloc] init];[queue addOperation:operation1];[queue addOperation:operation2];

NSOperation

Page 9: iOS-07_2 Multithreading

Асинхронность

NSOperationNSOperation *operation1, *operation2, *operation3;NSOperationQueue *queue;//...

operation1.queuePriority = NSOperationQueuePriorityLow;operation2.queuePriority = NSOperationQueuePriorityHigh;

[operation3 addDependency:operation1];[operation3 addDependency:operation2];

[queue addOperation:operation1];[queue addOperation:operation2];[queue addOperation:operation3];

Page 10: iOS-07_2 Multithreading

Асинхронность

NSOperation *operation1, *operation2;NSOperationQueue *queue;//...

operation1 = [[NSInvocationOperation alloc]initWithTarget:selfselector:@selector(printCount)object:nil];

operation2 = [[MyCustomOperation alloc] init];

[queue addOperation:operation1];[queue addOperation:operation2];

NSOperation

Page 11: iOS-07_2 Multithreading

Асинхронность

● NSThread○ Используется для длительных (или бесконечных) задач○ Явное создание потока (нужно использовать с умом)

● NSOperation○ Используется для логически обособленных задач○ Потоки создаются автоматически (например по количеству ядер процессора)○ Поддержка отмены операций○ Поддержка графа зависимостей между операциями○ Поддержка приоритезации операций

● GCD○ Лучшая производительность○ Относительно низкоуровневое C API○ Для простых задач — короткая запись○ Используется для быстрого перехода между главным и фоновым потоками

Асинхронность в iOS

Page 12: iOS-07_2 Multithreading

Асинхронность

dispatch_queue_t queue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(queue, ^{// Блок выполняется асинхронно

//...});

// Программа продолжает выполняться, не дожидаясь выполнения блока//...

GCD асинхронное выполнение

Page 13: iOS-07_2 Multithreading

Асинхронность

dispatch_queue_t queue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(queue, ^{// Блок выполняется асинхронно

//... dispatch_async(dispatch_get_main_queue(), ^{

// Выполнить в главном потоке// Например обновить UI, используя асинхронно полученные данные//...

});});

// Программа продолжает выполняться, не дожидаясь выполнения блока//...

GCD асинхронное выполнение

Page 14: iOS-07_2 Multithreading

Асинхронность

dispatch_queue_t queue1 = dispatch_queue_create("MyQueue1", NULL);dispatch_queue_t queue2 = dispatch_queue_create("MyQueue2", NULL);

void (^myBlock1)(void) = ^ {/*...*/};void (^myBlock2)(void) = ^ {/*...*/};void (^myBlock3)(void) = ^ {/*...*/};

dispatch_async(queue1, myBlock1);dispatch_async(queue2, myBlock2);dispatch_async(queue2, myBlock3);

GCD очереди

queue1

queue2

block1

block2 block3

Page 15: iOS-07_2 Multithreading

Асинхронность

GCD распараллеленное итерирование

int n = 42;dispatch_queue_t queue =

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_apply(n, queue, ^(size_t i) {// Выполнить 42 независимых операции,

// некоторые из них будут распараллелены. // i - номер текущей операции. //...});

// Сюда управление переходит когда все операции выполнены//...

Page 16: iOS-07_2 Multithreading

Асинхронность

GCD распараллеленное итерирование

int n = 42;dispatch_queue_t queue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(queue, ^{ dispatch_apply(n, queue, ^(size_t i) {

// Выполнить 42 независимых операции,// некоторые из них будут распараллелены.// i - номер текущей операции.//...

}); // Сюда управление переходит когда все операции выполнены //...});

// Сюда мы попадаем не дожидаясь выполнения предыдущего блока//...

Page 17: iOS-07_2 Multithreading

Асинхронность

GCD группы

dispatch_queue_t queue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_group_t group = dispatch_group_create();

dispatch_async(queue, ^{dispatch_group_async(group, queue, ^{

// Do some work 1.//...

}); // Do some work 2.//... dispatch_group_wait(group, DISPATCH_TIME_FOREVER);// Do some work 3.//... work 1

work 2 work 3время

Page 18: iOS-07_2 Multithreading

Асинхронность

+ (Singleton *)sharedInstance{

static Singleton *_sharedInstance = nil;if (_sharedInstance == nil) {

_sharedInstance = [[Singleton alloc] init];}return _sharedInstance;

}

Что произойдёт, если вызвать sharedInstance из двух разных потоков "одновременно", когда объект ещё не создан?

Потокобезопасность

Page 19: iOS-07_2 Multithreading

Асинхронность

GCD once

+ (Singleton *)sharedInstance{

static Singleton *_sharedInstance = nil;if (_sharedInstance == nil) {

_sharedInstance = [[Singleton alloc] init];}return _sharedInstance;

} + (Singleton *)sharedInstance{

static Singleton *_sharedInstance = nil;static dispatch_once_t predicate;dispatch_once(&predicate, ^{

_sharedInstance = [[Singleton alloc] init];});return _sharedInstance;

}

Page 20: iOS-07_2 Multithreading

Асинхронность

Потокобезопасность- (void)showCurrentData{

//...self.someLabel.text = self.someString;

} - (void)didReceiveSomeStringFromNetwork:(NSString *)someString{

self.someString = someString;[self showCurrentData];

}

Что произойдёт когда мы получим новые данные по сети (в фоновом потоке)?

Page 21: iOS-07_2 Multithreading

Асинхронность

- (void)showCurrentData{

void(^updateBlock)(void) = ^{self.someLabel.text = self.someString;

};

if ([NSThread isMainThread]) {updateBlock();

}else {

dispatch_async(dispatch_get_main_queue(), updateBlock);}

} - (void)didReceiveSomeStringFromNetwork:(NSString *)someString{

self.someString = someString;[self showCurrentData];

}

Потокобезопасность

Page 22: iOS-07_2 Multithreading

Асинхронность

Потокобезопасность- (void)showCurrentData{

//...self.someLabel.text = self.someString;

} - (void)didReceiveSomeStringFromNetwork:(NSString *)someString{

self.someString = someString;[self performSelectorOnMainThread:@selector(showCurrentData) withObject:nil waitUntilDone:NO];

}