如何在后台“准备”一个视图?

时间:2011-06-08 17:16:22

标签: iphone cocoa-touch ipad uiview uiviewcontroller

我有两个视图,第一个是一个简单的视图,其中介绍了一些使用方法,点击一个按钮就可以打开主视图。主视图有许多图像和两个自定义表,其中行由文本和图像组成,因此主视图的创建非常慢。探查器显示大部分时间由imageIO消耗(decode_mcu,png_read_filter_row,pmap_copy_page和decompress_onepass)

我希望在加载第一个视图后立即创建主视图进行优化,当我单击该按钮时,它只是将该视图设置为可见或将该视图置于前面。

我试图分配&在第一个视图的viewDidLoad

中初始化主视图
- (void)viewDidLoad
{
    [super viewDidLoad];
    rootVC = [[RootViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    rootVC.delegate = self;


}

并在按钮的操作方法

中执行此操作
- (IBAction)buttonUp:(id)sender {
    [self.view addSubview: rootVC.view];
}

但是这不起作用,加载仍然需要很长时间。我怎么能牺牲一些记忆来提供更好的用户体验呢?

由于

利奥

2 个答案:

答案 0 :(得分:8)

你应该:

  1. 使用Instruments查看代码花费最多的时间,并在那里进行优化。它可能不在你想的地方。

  2. 如果您正在使用UITableView,请了解如何按需创建UITableViewCells(而不是预加载大量数据)和循环实例(而不是重新创建它们)。

  3. 只有当Instruments指出这是瓶颈时:尝试在后台队列中加载/解压缩图像,然后在加载后更新主队列上的UIImageView(或其他)。 / p>

  4. 在iOS 4.x或更高版本中,您可以这样做:

    NSString *path = ...
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL), ^{
        // This is happening in the background thread.
        UIImage *image = [UIImage imageWithContentsOfFile:path];
        dispatch_async(dispatch_get_main_queue(), ^{
            // This is happening on the main thread; all UI updates must happen here.
            imageView.image = image;
        });
    });
    

    P.S。顺便说一句,UIViewController不会在创建时加载视图,而是按需加载。因此,基于上面的代码,表达式rootVC.view可能会触发要加载的视图。如果您想提前加载它,只需将rootVC.view放在其他地方。

答案 1 :(得分:4)

UIViewController尝试延迟加载其视图,即在实际需要之前不加载视图。如果你真的想强制你的视图控制器加载它的视图,你只需要访问它的视图属性,例如rootVC.view。

但是,你真的不应该这样做。例如,表视图仅创建在屏幕上可见的单元格,因此行数不太可能显着影响加载视图的时间。这里需要注意的是,有些事情可以真正减慢表格视图。例如,如果您在具有大量行的表中使用可变高度单元格,那么确实会减慢创建表的速度。尽量不这样做。

@benzado为改进性能提供了一些很好的指导。尝试对抗Cocoa-Touch始终是痛苦的一种方法,所以请尝试找出为什么您的视图需要很长时间才能加载。你的应用程序在哪里花费所有时间?你能做些什么来减轻负担?