1

私は現在、このようなことを行うコードをいくつか持っています(大幅に簡略化されていますが、要点を説明するのに十分です):

@property (weak) IBOutlet CustomViewClass *customView;

...

for (int i=0; i<iterations; i++) {

    // Crunch some data (Up to ~200,000 operations)...

    // Update view to represent where we are in the process:
    [_customView setNeedsDisplay:YES];

}

指定された回数の反復でコードを実行するたびに、カスタムビューのdrawRect:メソッドは、すべての反復が完了すると1回だけ呼び出されます。

私が望んでいるのは、すべての反復の後にビューを強制的に更新し、ビューが再描画されるまで待ってから次の反復に進むことです-しかし、ドキュメントのどこにも、私がそうするようにそれを機能させる方法が見つかりませんお気に入り!

drawRect:を直接呼び出すことができれば、問題は解決するように感じますが、NSViewではこれが許可されていないことはわかっています。

誰かが私を正しい方向に向けることができますか?

4

2 に答える 2

4

ビューの更新がないことは、現在のアプローチの最大の問題ではありません。最大の問題は、アプリケーションが終了するまでハングすることです。ユーザーは、キャンセル([キャンセル]ボタンを指定している場合)、非表示にするようにアプリケーションに指示する、作業の進行中にアプリケーションで他のことを行う、またはアプリケーションを終了することはできません。

正しいアプローチは、ループの本体をNSOperationに移動することです。これを行うには、NSOperationをサブクラス化するか、ブロックを使用してNSOperationを作成します。次に、すべての操作をキューに入れます。

ループで実行していることを安全に並行して実行できる場合は、キューを作成してそれを使用する必要があります。一度に1つの操作を実行する必要がある場合は、依存関係を使用して、各操作を前の操作にチェーンします。どうしてもメインスレッドで発生する必要がある場合は、メインキューを使用できますが、メインスレッドでは、安全に回避できる最小限の量を実行する必要があります。

作業が進むにつれて、ビューをに指示するメインスレッド/メインキューでコードを実行しますsetNeedsDisplay:。操作がメインキューにない(そこに配置していないと仮定)か、少なくとも分割されているため、これは作業の進行中に発生する可能性があります。

参考文献:

于 2012-12-16T01:30:25.607 に答える
1

これが必要かどうかはわかりませんが、CVDisplayLinkを使用してみてください。http://developer.apple.com/library/mac/#qa/qa1385/_index.html

于 2012-12-16T01:15:24.693 に答える