0

新しいCoreMotionフレームワークを使用して、一部のハードウェアデバイスを監視しています。これを行うための一般的なコードは次のとおりです。

-(void)startAccelerometer{
self.motion.accelerometerUpdateInterval = 1/30.0f;
NSOperationQueue* accelerometerQueue = [[NSOperationQueue alloc] init];
CMAccelerometerHandler accelerometerHandler = ^(CMAccelerometerData *accelerometerData, NSError *error) {

    NSLog(@"Accelerometer realtime values");
    NSLog(@"x=%f", accelerometerData.acceleration.x);
    NSLog(@"y=%f", accelerometerData.acceleration.y);
    NSLog(@"z=%f", accelerometerData.acceleration.z);
    NSLog(@"  ");

};
[self.motion startAccelerometerUpdatesToQueue:accelerometerQueue withHandler:[[accelerometerHandler copy]autorelease]];

}

それはうまくいきます。ここで、UILabelに値を出力したいのですが、CoreMotionフレームワークではブロックを使用するため、これがメインキューにあるとは限りません(実際、私のアプリではそうではありません)。このようにメインキューでラベルのセッターを実行するのは「間違っている」のでしょうか。

-(void)startAccelerometer{
self.motion.accelerometerUpdateInterval = 1/30.0f;
NSOperationQueue* accelerometerQueue = [[NSOperationQueue alloc] init];
CMAccelerometerHandler accelerometerHandler = ^(CMAccelerometerData *accelerometerData, NSError *error) {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.lblAccelerometer.text = [NSString stringWithFormat:@"Accelerometer:\nx = %f\ny = %f\nz = %f",
                                      accelerometerData.acceleration.x,
                                      accelerometerData.acceleration.y,
                                      accelerometerData.acceleration.z];

    });

};
[self.motion startAccelerometerUpdatesToQueue:accelerometerQueue withHandler:[[accelerometerHandler copy]autorelease]];

}

それはうまく機能し、これが眉をひそめる理由は私にはわかりません。それについて何か考えはありますか?

4

2 に答える 2

1

これは私が多くのプロジェクトで使用する一般的な方法です。UIの更新はメインスレッドで行う必要があります。

//Dispatch on background thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    //background processing goes here

    //Dispatch on main thread
    dispatch_async(dispatch_get_main_queue(), ^{
            //update UI here
    });
});

あなたの場合、UIの更新はメインスレッドで行われています。だから私は何も変更することを心配しません。

于 2012-07-31T02:48:11.830 に答える
0

簡単に言うと、ブロックの概念を誤解しています。

ブロックは、変数として処理でき、特定の時間またはスレッドで実行できる小さなコードです。

すべてのUI更新は、これを実行する限り問題がない限り、メインスレッドで実行する必要があります。

コードは、同期モードまたは非同期モードで、優先度の異なるさまざまなスレッドで実行できます。あなたのコードでは、それを完全にうまくやっています、あなたはそれをuiupdatesが実行されるべきであるメインキューにディスパッチするだけでなく、あなたはそれを非同期にディスパッチします、それはメインキューに送信を更新する最も安全な方法です(あなたのコードからこの特定のコードをメインキューとセカンダリキューのどちらから実行しているかはわかりませんが、同期ブロックをメインキューからメインキューにディスパッチすると、プログラムが機能しなくなります)

iOSドキュメントの場合:

dispatch_get_main_queue関数を使用して、アプリケーションのメインスレッドに関連付けられたシリアルディスパッチキューを取得します。このキューは、Cocoaアプリケーション、およびメインスレッドでdispatch_main関数を呼び出すか、実行ループを構成するアプリケーション(CFRunLoopRefタイプまたはNSRunLoopオブジェクトのいずれかを使用)に対して自動的に作成されます。

こちらをお読みくださいhttp://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html#//apple_ref/doc/uid/TP40008091-CH102-SW1

于 2012-07-31T02:16:10.060 に答える