在响应NSNotifications时,更新UIViews的最佳做法是什么

时间:2011-03-13 20:05:20

标签: iphone nsnotification

由于NSNotification在主线程以外的线程上调用其选择器,我注意到您对UIViews或其他接口元素所做的任何更改以响应该通知通常很慢生效。如果主线程很忙(这通常是我的话),这是最严重的。

我可以通过调用“performSelectorOnMainThread:”来解决问题。这真的是最好的做法吗?

- (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 个答案:

答案 0 :(得分:3)

NSNotificationCenter在您呼叫postNotification的同一线程上发送通知!所以它可能是主线程或后台线程。

顺便说一句,你不应该从非主线程中对UI进行更改,完全停止 - 它甚至不是缓慢的问题,你不应该这样做,事情可能会崩溃,等等。 / p>

您的解决方案当然是可行的,但有一种略有不同(可能更好)的方式。有关信息,请参阅此页:

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

总而言之,上述链接的方法通过实际调用方法在主线程上生成通知来处理问题,通过类别中的一些方便的帮助器方法。可能有用!与实际通知收据方法中调用performSelectorOnMainThread的解决方案相比,感觉有点'整洁',因为使用您当前的技术,您可能会在应用中收到通知时收到大量performSelectorOnMainThread来电。

此外,这是有用的信息:

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

答案 1 :(得分:2)

是。只应在主线程上调用所有与UI相关的方法。

您拥有的另一个选择是使用GCD并将其发送到主队列:

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

    [self setTintToNormal];
});

另外,请考虑waitUntilDone:NO。只要有可能,不要阻止。