При ответе на NSNotifications, что является лучшим методом для обновления UIViews - PullRequest
2 голосов
/ 13 марта 2011

Поскольку NSNotification вызывает свой селектор в потоке, отличном от основного потока, я замечаю, что любые изменения, которые вы вносите в UIViews или другие элементы интерфейса в ответ на это уведомление, часто медленно вступают в силу.Это наиболее остро, если основной поток занят (как часто бывает у меня!).

Я могу решить проблему, вызвав "executeSelectorOnMainThread:".Это действительно лучшая практика?

- (void) gotMovieSaveFinishNotication: (NSNotification *) not {
NSURL *exportMovieURL = (NSURL *) [not object];
//saving the composed video to the photos album
ALAssetsLibrary* library = [[[ALAssetsLibrary alloc] init] autorelease];

if(![library videoAtPathIsCompatibleWithSavedPhotosAlbum: exportMovieURL]) {
    NSLog(@"videoAtPathIsCompatibleWithSavedPhotosAlbum fails for: @",exportMovieURL);
    return;
}

[library writeVideoAtPathToSavedPhotosAlbum:exportMovieURL 
                            completionBlock:^(NSURL *assetURL, NSError *error)
 {
     [self performSelectorOnMainThread:@selector(setTintToNormal)
                            withObject: NULL
                         waitUntilDone: YES];

     if(error)
     {
         DLog(@"The video saving failed with the following error =============== %@",error);//notify of completion
     }
     else
     {
         DLog(@"The video is saved to the Photos Album successfully");

     }


 }];

}

Ответы [ 2 ]

3 голосов
/ 13 марта 2011

NSNotificationCenter отправляет уведомление в том же потоке, на котором вы звоните postNotification!Так что это может быть основной поток или фоновый поток.

Кстати, вы не должны вносить изменения в пользовательский интерфейс из неосновных потоков, полная остановка - это даже не вопрос медлительности, выпросто не стоит этого делать, вещи могут упасть и т. д.

Ваше решение, безусловно, работоспособно, но есть немного другой (и, возможно, лучший) способ.См. Эту страницу для информации:

http://www.cocoanetics.com/2010/05/nsnotifications-and-background-threads/

Подводя итог, можно сказать, что подход по приведенной выше ссылке решает проблему, фактически вызывая метод для генерации уведомления в главном потоке, через некоторыеудобные вспомогательные методы в категории.Может быть полезным!Чувствуется немного «аккуратнее», чем ваше решение о вызове performSelectorOnMainThread из фактического метода получения уведомлений, потому что с вашей текущей техникой вы можете получить множество вызовов performSelectorOnMainThread везде, где вы получите уведомление в своем приложении.

Также это полезная информация:

http://cocoadev.com/index.pl?NotificationsAcrossThreads

2 голосов
/ 13 марта 2011

Да.Все методы, связанные с пользовательским интерфейсом, должны вызываться только в главном потоке.

Другой вариант, который у вас есть, - это использовать GCD и отправить его в основную очередь:

dispatch_async(dispatch_get_main_queue(), ^{
    // do some stuff on the main thread here...

    [self setTintToNormal];
});

также, рассмотрим waitUntilDone: NO,По возможности не блокируйте.

...