6

いくつかのコードを操作していると、s 内で初めて実行ループに出くわしますNSOperation

s はデータのダウンロードでビジーです。ビジー状態の間、 s とスレッドのスリープNSOperationという形で、ダウンロードが完了するのを待つコードがあります。NSRunLoop

特にこのコードは私にとって興味深いものです:

while (aCertainConditionIsTrue && [self isCancelled]==NO) {
     if(![[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:1.0]]){
        [NSThread sleepForTimeInterval:1.0];
     }
}

実行ループについて読みましたがrunMode:beforeDate:、入力ソースまたはタイムアウトを待ちます。私は100%ではありませんが、入力ソースとしてカウントされます.

これを最初に実行すると、常に NO が返され、sleepForTimeInterval:. これは悪いですか?

特定のユーティリティ クラスでは、sleepForTimeInterval:スレッドごとに 1 回ずつ多くのヒットが発生し、パフォーマンスが大幅に低下します。

これに対するより良い解決策、またはアドバイスはありますか?

4

2 に答える 2

2

スリープすると、スレッドがロックされます。おそらく、コードを変更して performSelector:withObject:afterDelay を使用するでしょう。そうすれば、スレッドを実行し続けることができます。

    ...
    done = NO;
    [self checkDoneCondition:nil];
    ...

- (void)checkDoneCondition:(id)object {
    if (aCertainConditionIsTrue && [self isCancelled]==NO) {
        if(...) {
            [self performSelector:@selector(checkDoneCondition:) withObject:[con error] afterDelay:1.0];
        } else {
            done = YES;
        }
    }
}
于 2012-01-20T00:59:39.443 に答える
1

同時NSOperationを使用する必要があるようです。Apple ドキュメントの関連部分は次のとおりです。

同期的に実行される非同時操作とは対照的に、同時操作は非同期で実行されます。つまり、並行操作の start メソッドを呼び出すと、対応するタスクが完了する前にそのメソッドが戻る可能性があります。これは、操作オブジェクトがタスクを実行するための新しいスレッドを作成したか、操作が非同期関数を呼び出したために発生する可能性があります。制御が呼び出し元に戻ったときに操作が進行中かどうかは実際には問題ではなく、進行中の可能性があるということだけです。(...) 同時操作では、start メソッドが非同期で操作を開始します。スレッドを生成するか、非同期関数を呼び出すかに関係なく、このメソッドから実行します。運用開始にあたり、start メソッドは、isExecuting メソッドによって報告された操作の実行状態も更新する必要があります。これを行うには、isExecuting キー パスの KVO 通知を送信します。これにより、関心のあるクライアントは操作が実行中であることを知ることができます。isExecuting メソッドも、スレッドセーフな方法でステータスを返す必要があります。

( https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.htmlより)

つまり、-startNSOperation サブクラスのメソッドをオーバーライドし、executingandfinishedプロパティに ivar を使用できます。このメソッドは、別のスレッドでダウンロードを開始します。ダウンロードが開始したら、executingフラグを設定して KVO をトリガーします。このスレッドで終了したら、 と で同じことをfinished行いexecutingます。複雑に見えますが、実はとてもシンプルです。

スタック オーバーフローに関するこの質問も参照してください。優れた説明があります。

于 2012-03-09T21:14:05.200 に答える