2

NSOperation と NSOperationQueue (2D ゲームの場合) を使用してバックグラウンドで画像を読み込んでいます。

NSOperations の動作を理解するために、次の無関係な NSOperationQueue / NSOperation を追加してみました (画像の読み込みを開始する前に -startNewEndlessBackgroundTask を呼び出します)。

static int stop = NO;
static int c = 1000;
-(void)takeTime {
    stop = NO;
    while (!stop) {
        for (int i = 0; i < 10000; i++) {
            c += 1;
        }
        c = c;
    }
}
-(void)stopBackgroundTask {
    stop = YES;
}
-(void)startNewEndlessBackgroundTask {
    //[self performSelectorInBackground:@selector(takeTime) withObject:nil];
    NSOperationQueue* queue = [[NSOperationQueue alloc] init];
    [queue addOperationWithBlock:^{
         [self takeTime];
    }];
}

これにより、iPhone4 での画像の読み込みのために、他の NSOperationQueue が完全にブロックされます。iPhone4s では、startNewEndlessBackgroundTask を 2 回呼び出した後、画像の読み込みがブロックされます。どちらもiOS 6を実行しています。

アプリのメイン ループがブロックされていません。

代わりに performSelectorInBackground を使用して takeTime を呼び出すと、すべてがブロックされることなく正常に動作し、バックグラウンドでも takeTime ルーチンが適切に動作します。

2 つの NSOperationQueue が完全に別々に割り当てられ、依存関係がない場合、なぜこれが起こるのでしょうか? 私にとって、この単純な方法で NSOperationQueue を使用することと performSelectorInBackground を使用することの間に違いはないはずですが、誤解している基本的なものがあると思いますか?

4

1 に答える 1

0

詳細についてはわかりませんが、これは私が今起こっていると思うことに対する部分的な答えです..

NSOperation は下で GCD を使用します (少なくとも、OSX と iOS の最後のいくつかのバージョン以降)。GCD には特定のグローバル プライオリティ キューがあります。

優先度の高いキューにタスクがある場合、優先度の低いキューのタスクは開始されません (同じグローバル優先度キューのタスクは開始できますが、名前に「キュー」が含まれているにもかかわらず、デフォルトの優先度キューのタスクは開始できます)。同時であること)。

スレッドの優先度を指定していないので、-takeTime 操作はデフォルトの優先度キューでスケジュールされ、イメージの読み込み操作はデフォルトの低優先度キューでスケジュールされていたと思います。これは、-takeTime 操作がイメージの読み込みをブロックしていた理由を説明します。

これが実際に説明していないのは、iPhone 4s でイメージの読み込み操作をブロックするのに 2 つの -takeTime 操作が必要な理由です。 CPUコアの数 - ドキュメントで見た限り。

Apple - Dispatch Queues : 「デフォルトの同時実行キューを取得することに加えて、代わりに DISPATCH_QUEUE_PRIORITY_HIGH および DISPATCH_QUEUE_PRIORITY_LOW 定数を関数に渡すことで、高優先度および低優先度レベルのキューを取得するか、DISPATCH_QUEUE_PRIORITY_BACKGROUND を渡すことでバックグラウンド キューを取得することもできます。ご想像のとおり、高優先度の同時キュー内のタスクは、デフォルトおよび低優先度のキュー内のタスクよりも先に実行されます。同様に、デフォルト キュー内のタスクは、低優先度のキュー内のタスクよりも先に実行されます。"

于 2013-03-11T13:48:54.117 に答える