2

私のアプリケーションは、たくさんのForループで多くの作業を行います。大量の文字列を計算し、完了するまでに1分以上かかる場合があります。

そこで、NSProgressIndicatorをアプリに配置しました。

ループ内で、NSProgressIndicatorの「incrementBy」関数を使用しました。ただし、実際のバーがいっぱいになることはありません。

これは、ループが可能な限りすべての電力を消費しているためであると思われます。したがって、NSProgressIndicatorは(グラフィカルに)更新されません。

では、どうすればそれを進歩させることができますか?

4

1 に答える 1

5

forループはメイン スレッドまたはバックグラウンド スレッドで実行されていますか? それらがメイン スレッドで実行されている場合、GUI は進行状況の変更を反映するためにそれ自体を更新する機会を得ることはありません。これは実行ループの最後、つまり関数の実行が終了した後にのみ発生するためです。

forループがバックグラウンドで実行されている場合、あなたはいたずらをしています! メイン スレッド以外のどこからでも GUI を更新しないでください。最新のシステムをターゲットにしている場合は、GCD を使用してこれを簡単に回避できます。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
    for (int i = 0; i < n; i++) {
        // do stuff
        dispatch_async(dispatch_get_main_queue(), ^(void) {
            // do your ui update here
        });
    }
});

または、ループを書き直してforGCD をさらに活用し、 を使用することもできますdispatch_apply。上記に相当するものは次のとおりです。

dispatch_apply(n, DISPATCH_QUEUE_PRIORITY_DEFAULT, ^(size_t i) {
    // for loop stuff here
    dispatch_async(dispatch_get_main_queue(), ^(void) {
        // do your ui update here
    });
});

usingdispatch_applyは、ループの各「反復」が相互に同時に実行される可能for性があることを意味するため、ループをシリアルに実行する必要がある場合、これは適用されないことに注意してください。

于 2011-08-22T01:48:20.323 に答える