6

私は、さまざまなコールバックを使用して一連の非同期操作を行うコードを使用しています。Snow Leopard は、ブロックと GCD を使用してこれを非常に簡単にしました。

私は次NSTaskのように呼び出してNSBlockOperationいます:

[self.queue addOperationWithBlock:^{
    NSTask *task = [NSTask new];
    NSPipe *newPipe = [NSPipe new];
    NSFileHandle *readHandle = [newPipe fileHandleForReading];
    NSData *inData = nil;
    [task setLaunchPath:path];
    [task setArguments:arguments];
    [task launch];

    while ((inData = [readHandle availableData]) && [inData length]) {
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            // callback
        }];
    }

    [task waitUntilExit];
}];

このアプローチは完全に機能します。コールバックが同時実行を正しく処理する限り、これはまるで魔法のようです。

ここで、これらの呼び出しのいくつかを結合できるようにしたいと考えています。これはモデル オブジェクトの「refresh」メソッド内にあり、完了するまでに時間がかかる場合があります。ユーザーが更新ボタンを押しても、マシンなどすべてが拘束されることはありません。

ここで実装のジレンマを見ることができます。一連のキュー (呼び出しの種類ごとに 1 つ) を作成し、それらの同時操作数を 1 に設定し-cancelAllOperationsて、新しい呼び出しの時間になるといつでも呼び出すことができます。

別の方法として、現在発生している呼び出しを手動で記録し、モデル オブジェクトごとに 1 つのキューを管理することも (私が行っているように)、さらに進んでグローバル キューを使用することもできます。

の重さはNSOperationQueue?多くのキューを作成することは、アーキテクチャ上の決定として不適切ですか? これらのタスクを結合するためのより良い方法はありますか?

4

3 に答える 3

8

パフォーマンスが気になる場合は、推測しないでください。測定してから、見つかったボトルネックを修正してください。キューの追加は簡単です。試してみて、Instruments がパフォーマンスへの影響について教えてくれることを確認してください。

複数のキューを作成する主な理由は、それらを開始および停止する何らかの理由がある場合です。libdispatch の利点を得たいだけであれば、操作をメイン キューに追加するだけでそれを得ることができます。

于 2009-10-03T08:07:18.827 に答える
1

同時に実行される NSBlockOperation に複数のブロックを追加でき、含まれている操作をキャンセルすることでキャンセルできます。個々のタスクをシリアル化する必要がない限り、これは機能する可能性があります。

于 2009-10-03T14:40:17.557 に答える
0

操作キューを好きなだけ使用してください。それらは、プログラムの論理的な部分を分離するためにここにあります。毎秒数百のキューを割り当てていない限り、パフォーマンスについてあまり気にする必要はないと思います。

于 2009-10-03T08:32:20.757 に答える