我有一个自定义视图控制器,它实现了来自UITableViewDataSource
和UITableViewDelegate
协议。当我为我的表加载数据时(在我的viewDidLoad
方法中),我创建了一个NSOperationQueue
和一个NSInvocationOperation
并将其添加到队列中。我抛出了一个活动指示器,viewDidLoad
退出。
用于操作的方法结束活动指示器动画。
我注意到当操作完成时,在操作真正完成之前有一个5-7秒的暂停,即使NSLog看起来像是返回了操作的方法。
我曾尝试使用Instruments来确定暂停发生的位置,但我无法分辨,因为我的大部分CPU时间都花在了系统库中。
修改 这是一个缩写版本:
@implementation MyViewController
@synthesize ...
- (void)viewDidLoad {
[super viewDidLoad];
self.opsQueue = [[NSOperationQueue alloc] init];
NSInvocationOperation *aiStartOp = [[[NSInvocationOperation alloc]
initWithTarget:self
selector:@selector(showActivityIndicators)
object:nil] autorelease];
[self.opsQueue addOperation:aiStartOp];
NSInvocationOperation *dataOp = [[[[NSInvicationOperation alloc]
initWithTarget:self
selector:@selector(dataUpdate)
object:nil] autorelease];
[dataOp addDependency aiStartOp];
[self.opsQueue addOperation:dataOp];
NSInvicationOperation *aiStopOp = [[[NSInvicationOperation alloc]
initWithTarget:self
selector:@selector(hideActivityIndicators)
object:nil] autorelease];
[aiStopOp addDependency:dataOp];
[self.opsQueue addOperation:aiStopOp];
}
/* other stuff */
@end
为了清楚起见,队列中的最后一个操作是:
- (void)hideActivityIndicators {
DLog(@"hiding activity indicator");
self.portraitChartProgressView.hidden = YES;
[self.portraitChartProgressIndicator stopAnimating];
self.landscapeProgressView.hidden = NO;
[self.landscapeProgressIndicator startAnimating];
}
我在日志中看到的是上面日志消息的输出,然后是5秒的暂停,最后是视图,其中隐藏了指示符。
有什么想法吗?
答案 0 :(得分:3)
需要在主线程上执行所有UI事件,绘图等。 您可以使用以下内容将呼叫转发到主线程。
- (void)hideActivityIndicators {
if (![NSThread isMainThread])
[self performSelectorOnMainThread:@selector(hideActivityIndicators) withObject:nil waitUntilDone:NO];
DLog(@"hiding activity indicator");
self.portraitChartProgressView.hidden = YES;
[self.portraitChartProgressIndicator stopAnimating];
self.landscapeProgressView.hidden = NO;
[self.landscapeProgressIndicator startAnimating];
}
修改“强>
现在我更仔细一点,你可能不需要做的一件事就是通过添加NSOperationQueue
来启动和停止“加载”视图。可能您需要在队列中做的唯一事情是数据更新,然后发布通知和委派以在数据操作完成时更新您的视图。
TopSongs示例项目非常好地展示了这一点。主线程的转发语句基于示例中AppDelegate.m文件中的代码。