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.
精彩评论