0

良い一日、

日付項目などを選択するたびに setneedslayout を使用して再描画する必要がある複雑なカレンダー コントロールがあります。これを GCD ブロックで実行しようとしましたが、実行されませんでした。ただし、メインスレッドで実行するとsetNeedsLayoutが実行され、機能します。ただし、これにより、ユーザー エクスペリエンスを破壊する厄介なスタッター/ラグがプログラムに発生します。

何ができるかを知ることができますか?これを別のスレッドで実行できますか? NSTimer を使用したり、別のスレッドでセレクターを実行したりできますか?

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
    dispatch_async(dispatch_get_main_queue(), ^{
        //[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    });
    @try {
        NSLog(@"New Thread");

        if (self.selectedDate) {
            [datesToReload addObject:self.selectedDate];
        }
        if (date) {
            [datesToReload addObject:date];
        }
        self.selectedDate = date;
        [self reloadDates:datesToReload];

        [self performSelectorOnMainThread:@selector(reloadDates:) withObject:datesToReload waitUntilDone:NO];
        //[self perform]

        if (visible && date) {
            self.monthShowing = date;
        }
    }
    @catch (NSException *exception) {
        NSLog(@"Exception = %@", exception);
    }
    dispatch_async(dispatch_get_main_queue(), ^{
        //[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        NSLog(@"Main Thread");
    });
});
4

2 に答える 2

0

上記のコード例を使用した提案:

1) reloadDates を 2 回呼び出しています。perform_selector を使用した 2 回目の呼び出しまでビューが正常に更新されなかったとしても、同じ作業を 2 回行っていることになります。これだけでも、reloadData メソッドで発生している UI の遅延が 2 倍になります。

2) 作業の大部分には優先度の低いキューを使用します。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{

    if (self.selectedDate) {
        [datesToReload addObject:self.selectedDate];
    }

    if (date) {
        [datesToReload addObject:date];
    }

    self.selectedDate = date;
    [self reloadDates:datesToReload];

    if (visible && date) {
        self.monthShowing = date;
    }

});

reloadDates 内では、メイン キューの非同期ブロックに setNeedsLayout 呼び出しのみを配置します。

それが完了しても、UI の遅延が許容できないレベルである場合は、再描画されているビューを調べて、それを高速化する方法を確認する必要があります。Instruments の Time Profiler は、これらの再描画イベント中にどこで CPU 時間を使用しているかを確認するための適切な最初のステップです。

于 2013-05-24T20:26:55.923 に答える