UILabel没有使用线程立即显示

时间:2013-03-05 16:40:45

标签: ios objective-c uiview uilabel grand-central-dispatch

我想在线程中加载一些视图以避免UI冻结等待加载结束。

我不习惯线程,所以我做了一个快速测试。我的代码只是尝试在线程中创建视图,并在主线程的当前viewcontroller视图中添加此视图。

我的UIView正在工作,但对于我的UILabel,我必须等待20到60秒才能将它放在屏幕上。

我使用UIButton进行测试,在这种情况下,按钮会立即显示,但按钮内的标签显示的延迟与我的UILabel相同。

让它按我想要的方式工作的唯一方法是添加一个[lbl setNeedsDisplay];在主线程中强制UILabel立即显示。 为什么?没有这条线就可以完成这项工作吗?

    dispatch_queue_t queue = dispatch_queue_create("myqueue", NULL);
dispatch_async(queue, ^{

    // NEW THREAD
    UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 48)];
    lbl.text = @"FOO";

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
    view.backgroundColor = [UIColor redColor];

    // MAIN THREAD
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.view addSubview:lbl];
        [lbl setNeedsDisplay]; // Needeed to see the UILabel. WHY???

        [self.view addSubview:view];
    });
});
dispatch_release(queue);

1 个答案:

答案 0 :(得分:5)

您还应该在主队列上设置标签的文本:

dispatch_async( dispatch_get_main_queue(), ^{
    UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 48)]
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
    lbl.text = @"FOO";
    [self.view addSubview:lbl];
    [self.view addSubview:view];
});

最好将所有 UI内容保留在主队列中。

<强>更新

看来initWithFrame:不是线程安全的(在SO answer上找到,另请参阅UIView文档中的Threading Considerations)。