我有一个ViewController需要时间来加载它的视图。当我运行Instruments时,我在主屏幕上看到,如果我点击将该视图控制器推到堆栈上的图标,它将一半布置视图,一半获取视图的数据。当按下按钮将LongRunningViewController推入堆栈时,我尝试添加一个活动指示器以在主屏幕上显示。所以我基本上这样做:
- (IBAction)puzzleView:(id)sender {
dispatch_async(dispatch_get_main_queue(), ^{
[self.activityIndicator startAnimating];
});
PuzzleViewController *detailViewController = [[[PuzzleViewController alloc] init] autorelease];
[self.navigationController pushViewController:detailViewController animated:YES];
[self.activityIndicator stopAnimating];
}
按住按钮时主屏幕滞后,然后加载视图。我正在尝试显示活动指示器,而另一个屏幕正在准备推送(或至少这是我认为它的工作方式)。但是,活动指标未显示。我想知道这是否可以做到?或者其他应用程序推送他们的ViewController,然后在该屏幕上,他们有活动指示器显示其不同资源的加载?
答案 0 :(得分:9)
当你说获取视图的数据需要时间时,我认为你的意思是PuzzleViewController
在viewDidLoad
之类的地方做了一件非常重要的事情。
所以我们说它在viewDidLoad
。然后你可以这样做:
-(void)viewDidLoad
{
[self.activityIndicator startAnimating];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{
//do something expensive
[self doSomethingExpensive];
//dispatch back to the main (UI) thread to stop the activity indicator
dispatch_async(dispatch_get_main_queue(), ^
{
[self.activityIndicator stopAnimating];
});
});
}
这意味着昂贵的操作将放在后台线程上,并且不会阻止视图控制器的加载/显示。
当用户按下按钮并在该屏幕上显示进度时,此方法立即显示请求的视图。我认为这种方式比在呈现视图之前加载内容时显示活动视图更常见。这也给你带来了更多的时间;在转换动画期间,您的长时间操作可以在后台运行!
您的活动视图未显示您正在执行此操作的方式的原因是您在UI线程上执行了所有操作;从主队列使用dispatch_async
到主队列将无法完成任何事情,因为在运行循环完成之前,您的块将无法运行。