3

UI フリーズ待ちの読み込み終了を回避するために、いくつかのビューをスレッドに読み込みたいと考えています。

私はスレッドに慣れていないので、簡単なテストを行います。私のコードは、スレッドでビューを作成し、このビューをメインスレッドの現在のビューコントローラービューに追加しようとしています。

私の 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);
4

1 に答える 1

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の回答あります。ドキュメントのスレッドに関する考慮事項も参照してください)。UIView

于 2013-03-05T16:45:55.173 に答える