开发者

When responding to NSNotifications, what is the best practice for updating UIViews

Since the NSNotification invokes its selector on a thread other than the main thread, I notice that any changes that you make to UIViews or other interface elements in response to that notification are often slow to take effect. This is most acute if the main thread is busy (as mine often is!).

I can solve the problem by calling "performSelectorOnMainThread:". Is this really the best practice?

- (void) gotMovieSaveFinishNotication: (NSNotificati开发者_StackOverflow社区on *) 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");

     }


 }];

}


NSNotificationCenter sends the notification on the same thread that you call postNotification on! So it could be the main thread, or a background thread.

Btw, You shouldn't be making changes to the UI from non-main threads, full stop -- it's not even a matter of slowness, you just shouldn't be doing it, things can fall over, etc.

Your solution certainly is workable, but there's a slightly different (and possibly better) way. See this page for info:

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

To summarise, the approach at the above link deals with the problem by actually calling the method to generate a notification on the main thread, via some handy helper methods in a category. Could be useful! Feels a bit 'neater' than your solution of calling performSelectorOnMainThread from the actual notification receipt method, because with your current technique you could end up with lots of performSelectorOnMainThread calls whereever you receive a notification in your app.

Also, this is useful info:

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


Yes. All UI related methods should only be called on the main thread.

The other option you have is to use GCD and send it to main queue:

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

    [self setTintToNormal];
});

also, consider waitUntilDone:NO. Whenever possible, don't block.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜