在后台线程加载UI好吗?

时间:2015-08-21 19:04:52

标签: ios objective-c multithreading uiviewcontroller

我的应用目前由TableViewControllerViewController组成。选中cell中的TableView后,会推送ViewController,这是主应用。此视图控制器先前在主线程中加载了所有UIViews,这导致屏幕在代码运行时冻结,通常会导致用户认为它已崩溃。为了防止出现此问题并改善用户体验,我将代码更改为以下整体格式:

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.

[self initialiseApp];

}

- (void) initialiseApp {

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //Initialising views

    imageView = [[UIImageView alloc] initWithImage:[self getImageFromUrl:currentWallpaperURL]];
    [imageView setFrame:CGRectMake(0.0, 100, screenWidth, (screenWidth/7)*4)];
    [imageView setContentMode:UIViewContentModeScaleAspectFit];

// etc etc for other views

    dispatch_async(dispatch_get_main_queue(), ^{
        //Add subviews to UI

        [[self view] addSubview:imageView];
    });
});

}

当应用在模拟器中运行时,这会导致ViewController作为空白屏幕加载,之后会在一段时间后加载UI。在加载过程中,我会在屏幕上显示某种形式的微调器或文本。因此,我想澄清一下这个主题:

UI打开时(或应用程序启动时)加载应用程序ViewController是否为常规?如果没有,什么是更好的替代方案,以防止应用程序在启动时冻结10秒?

感谢。

1 个答案:

答案 0 :(得分:7)

在后台线程上创建UI元素时,我会遇到问题,所以如果可能的话,我会避免这种情况(Apple says the same)。在您的情况下,不是在后台加载UI元素,而是在后台加载图像,然后在加载图像时创建UI元素。例如,

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    UIImage *image = [self getImageFromUrl:currentWallpaperURL];
    dispatch_async(dispatch_get_main_queue(), ^{
        //Add subviews to UI
        imageView = [[UIImageView alloc] initWithImage:image];
        [imageView setFrame:CGRectMake(0.0, 100, screenWidth, (screenWidth/7)*4)];
        [imageView setContentMode:UIViewContentModeScaleAspectFit];
        [[self view] addSubview:imageView];
    });
});