2013-10-24 20 views
6

内startDeviceMotionUpdatesToQueueを呼び出すときに、私は怠惰なインスタンス化を行う、私はそのゲッターでCMMotionManager私のルートコントローラでは、コントローラ

@property (strong, nonatomic) CMMotionManager *MManager; 

のプロパティを持たOSSpinLockLockを取得します。場合は、コントローラのビューのロード、私は私のミスは何ですか?

libsystem_platform.dylib`spin_lock$VARIANT$mp: 
0x39a87814: movs r1, #1 

libsystem_platform.dylib`OSSpinLockLock$VARIANT$mp + 2: 
0x39a87816: ldrex r2, [r0] 
0x39a8781a: cmp r2, #0 
0x39a8781c: it  ne 
0x39a8781e: bne.w 0x39a893ec    ; _OSSpinLockLockSlow$shim 
0x39a87822: strex r2, r1, [r0] 
0x39a87826: cmp r2, #0 
0x39a87828: bne 0x39a87816    ; OSSpinLockLock$VARIANT$mp + 2 
0x39a8782a: dmb ish 
0x39a8782e: bx  lr 

私が見 NSLogに「アウェイ私達は行く」と、すぐにアプリがクラッシュすると、私はこのスレッドのログを取得
- (void)reloadAccelerometer { 
    NSLog(@"Away we go"); 
    self.MManager.deviceMotionUpdateInterval = 10.0/60.0; 
    [self.MManager startDeviceMotionUpdatesToQueue:self.queue withHandler:^(CMDeviceMotion *motion, NSError *error) { 
     NSLog(@"Y values is: %f", motion.userAcceleration.y); 
    }]; 
} 

このメソッドを呼び出しますか私は reloadAccelerometerを間違った場所に置いたのですか?

答えて

6

私はiOSアプリで同様のことをやろうとしていて、は永遠にで、クラッシュの原因を突き止めようとしました。これは非常に暗い(そして厄介な)例外でした。 OSSpinLockスレッド/キュー管理の問題と関係しているというクラッシュレポートを読んだ後、私は結局それを理解しました。

NSOperationQueueはここでの犯人です。あなたはNSOperationQueueを作成し、どのようにあなたのコードが表示されませんが、私はそれがこのようなものだったと仮定します。

NSOperationQueue *aQueue = [[NSOperationQueue alloc] init]; // Do NOT do this 
[self.MManager startDeviceMotionUpdatesToQueue:aQueue withHandler:^(CMDeviceMotion *motion, NSError *error) { 
    NSLog(@"Y values is: %f", motion.userAcceleration.y); 
}]; 

それは、これがないNSOperationQueueを使用する方法であることが判明しました。そのaQueueオブジェクトがクラッシュの原因です。

操作キューを正しく設定してクラッシュを回避するには、CMMotionManagerを別のスレッドに移動する必要があります。次に、currentQueueを使用するようにNSOperationQueueに指示します(mainQueueではなく)。 AppleはmainQueueで実行されていないことをお勧めしますが、あなたのアプリが現在メインキューで実行されている場合、currentQueueの違いはわかりません。私はGCDを使って下のコードを別のキューに移動しようとしましたが、コードは一度も呼び出されませんでした。ここで

は、あなたの最終的なコードがどのように見えるかです:

// Check if Motion/Location services are available 
if (motionManager.deviceMotionAvailable == YES && motionManager.accelerometerAvailable == YES) { 
    NSLog(@"Away we go"); 
    self.MManager.deviceMotionUpdateInterval = 10.0/60.0; 
    [self.MManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) { 
     NSLog(@"Y values is: %f", motion.userAcceleration.y); 
    }]; 
} else { 
    // Motion/Accelerometer services unavailable 
} 

また、私は(私の知る限りでは)CMMotionManagerプロパティのあなたの作成が(strong, nonatomic)で正しいであることに注意してください。

+1

うわー、華麗な答え!ありがとうRazorSharp :) –

関連する問題