2

異なるスレッド優先度と同時にバックグラウンドで実行する必要がある2つのタスクがあります。

  1. ジャイロモーションデータを継続的に収集して処理します(優先度が高い)

    gyroQueue = [[NSOperationQueue alloc] init];
    
    [self.motionManager startDeviceMotionUpdatesToQueue:gyroQueue withHandler:^(CMDeviceMotion *motion, NSError *error){
        [self processMotion:motion withError:error];
    }];
    
  2. モーションの更新(変換、トリミング、サイズ変更など= 1〜2秒)に干渉することなく画像を処理する場合があります(優先度が非常に低い)

    imageProcessingQueue = [[NSOperationQueue alloc] init];
    
    [imageProcessingQueue addOperationWithBlock:^{
        [self processImage:[UIImage imageWithData:imageData]];
    }];
    

編集:これは私が最初に(ブロック操作の代わりに)配置していたものであり、それでもモーションの更新をブロックしています:

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(processImage:) object:[UIImage imageWithData:imageData]];
[operation setThreadPriority:0.0];
[operation setQueuePriority:0.0];
[imageProcessingQueue addOperation:operation];

これらのタスクは両方とも同じバックグラウンドスレッドで実行されているようで(NSOperationQueueの性質のため?)、画像の処理は、完了するまでgyroQueueの更新をブロックします。これは私が避けようとしていることです。

NSOperationQueueを使用して2つの別々のスレッドを生成し、それに応じてveryHighとveryLowの優先度を割り当てるにはどうすればよいですか?

編集:この質問はまだ開いています、私は画像のサイズ変更のためにトラバーハーモンの画像サイズ変更機能を使用しています。誰かがそれがスレッドセーフかどうかを確認できますか?

4

2 に答える 2

0

ここでは、操作キューを1つだけ作成して、必要に応じて各操作の優先度を設定してみることができると思います。スレッドの優先順位はより効果的であり、キューを1つだけ使用する場合は、よりクリーンな方法で考えるようになります(結局のところ、これは単なる提案です)。

- (void)setThreadPriority:(double)priority

指定した値は、オペレーティングシステムの優先度の値にマップされます。指定されたスレッド優先度は、操作のmainメソッドが実行されている間のみスレッドに適用されます。操作の完了ブロックの実行中は適用されません。独自のスレッドを作成する並行操作の場合、カスタムstartメソッドでスレッドの優先度を自分で設定し、操作の終了時に元の優先度をリセットする必要があります。

アップルのドキュメントから。

Operation queues usually provide the threads used to run their operations. In Mac OS X v10.6 and later, operation queues use the libdispatch library (also known as Grand Central Dispatch) to initiate the execution of their operations. As a result, operations are always executed on a separate thread, regardless of whether they are designated as concurrent or non-concurrent operations. In iOS 4 and later, operation queues use Grand Central Dispatch to execute operations.

于 2012-07-18T05:32:25.910 に答える
0

私はこの問題の解決策(または確実な回避策)を見つけました:

を使用してdeviceMotionの更新をキューにルーティングする代わりにstartDeviceMotionUpdatesToQueue、CADisplayLinkタイマーを作成しましたが、他のバックグラウンドキューに干渉していません。画面のリフレッシュレートと一致している間は、その性質上、最高の優先度が与えられます。

[self.motionManager startDeviceMotionUpdates];

gyroTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(processMotion)];
[gyroTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
于 2013-04-07T22:25:00.687 に答える