由于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");
}
}];
}
答案 0 :(得分:3)
NSNotificationCenter在您呼叫postNotification
的同一线程上发送通知!所以它可能是主线程或后台线程。
您的解决方案当然是可行的,但有一种略有不同(可能更好)的方式。有关信息,请参阅此页:
http://www.cocoanetics.com/2010/05/nsnotifications-and-background-threads/
总而言之,上述链接的方法通过实际调用方法在主线程上生成通知来处理问题,通过类别中的一些方便的帮助器方法。可能有用!与实际通知收据方法中调用performSelectorOnMainThread
的解决方案相比,感觉有点'整洁',因为使用您当前的技术,您可能会在应用中收到通知时收到大量performSelectorOnMainThread
来电。
此外,这是有用的信息:
答案 1 :(得分:2)
是。只应在主线程上调用所有与UI相关的方法。
您拥有的另一个选择是使用GCD并将其发送到主队列:
dispatch_async(dispatch_get_main_queue(), ^{
// do some stuff on the main thread here...
[self setTintToNormal];
});
另外,请考虑waitUntilDone:NO。只要有可能,不要阻止。