2

私には時間のかかるプロセスがあり、物事がどこまで進んだかをユーザーに示す進行状況インジケーターがあります。メインスレッドで消費することをしなければならないので、更新の間にメインキューに更新を単にディスパッチするオプションがありません。UIを更新してから元に戻して続行するには、しばらくの間バックグラウンドスレッドに切り替える必要があります。

これは私が持っているものですが、それは非常に非正統的だと感じています。私が見逃している「UIへのコールバックを伴うループのブロック」を行うためのより良い方法はありますか?また、これが最終的にブロックの割り当てを実際に解除するかどうかも完全にはわかりませんが、それは別の話です。

__block NSUInteger i = 0;
__block dispatch_block_t obtainBlock;

obtainBlock = [^{
    [self obtainAssetAtIndex:i];
    progressView.progress += progressPerFile;
    i++;
    if (i < assets.count) {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
            usleep(500);
            dispatch_async(dispatch_get_main_queue(), obtainBlock);
        });
    } else {
        [self didImportGroup];
        [obtainBlock release];
    }
} copy];

dispatch_async(dispatch_get_main_queue(), obtainBlock);
4

1 に答える 1

3

複雑すぎる考え方。現在のセットアップ:

  1. 一つの仕事をする
  2. コントロールをバックグラウンド スレッドに渡す
  3. バックグラウンドで寝る
  4. メインスレッドで次の作業をスケジュールする

やりたいこと:

  1. 一つの仕事をする
  2. 次の作業のスケジュールを立てる

コードは次のとおりです。

- (void)doWork
{
    if (_assetIndex < assets.count) {
        [self obtainAssetAtIndex:_assetIndex++];
        progressView.progress += progressPerFile;
        [self performSelector:@selector(doWork) withObject:nil afterDelay:0];
    } else {
        [self didImportGroup];
    }
}

バックグラウンド スレッドはまったく必要ありません (特に、これまでにスリープしているだけの場合)。

于 2012-07-26T17:29:18.293 に答える