ios – 在控制器内调用startDeviceMotionUpdatesToQueue时得到OSSpinLockLock

前端之家收集整理的这篇文章主要介绍了ios – 在控制器内调用startDeviceMotionUpdatesToQueue时得到OSSpinLockLock前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在我的根控制器中,我有一个CMMotionManager属性
  1. @property (strong,nonatomic) CMMotionManager *MManager;

在它的吸气器中我做懒惰的实例化.当控制器的视图加载时,我调用方法

  1. - (void)reloadAccelerometer {
  2. NSLog(@"Away we go");
  3. self.MManager.deviceMotionUpdateInterval = 10.0/60.0;
  4. [self.MManager startDeviceMotionUpdatesToQueue:self.queue withHandler:^(CMDeviceMotion *motion,NSError *error) {
  5. NSLog(@"Y values is: %f",motion.userAcceleration.y);
  6. }];
  7. }

我在NSLog中看到“Away we go”,然后应用程序立即崩溃,我得到了这个线程日志

  1. libsystem_platform.dylib`spin_lock$VARIANT$mp:
  2. 0x39a87814: movs r1,#1
  3.  
  4. libsystem_platform.dylib`OSSpinLockLock$VARIANT$mp + 2:
  5. 0x39a87816: ldrex r2,[r0]
  6. 0x39a8781a: cmp r2,#0
  7. 0x39a8781c: it ne
  8. 0x39a8781e: bne.w 0x39a893ec ; _OSSpinLockLockSlow$shim
  9. 0x39a87822: strex r2,r1,[r0]
  10. 0x39a87826: cmp r2,#0
  11. 0x39a87828: bne 0x39a87816 ; OSSpinLockLock$VARIANT$mp + 2
  12. 0x39a8782a: dmb ish
  13. 0x39a8782e: bx lr

我的错是什么?我把reloadAccelerometer放在错误的地方吗?

解决方法

我试图在我的iOS应用程序中做类似的事情,并花了很多时间试图弄清楚崩溃的原因是什么.这是一个非常神秘(而且讨厌)的例外.在阅读了OSSpinLock与线程/队列管理问题有关的崩溃报告后,我最终弄明白了.

NSOperationQueue是罪魁祸首.您的代码没有显示您是如何创建NSOperationQueue的,但我认为它是这样的:

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

事实证明,这不是使用NSOperationQueue的方法.那个aQueue对象是崩溃的原因.

要正确设置操作队列并避免崩溃,您应该将CMMotionManager移动到其他线程.然后告诉NSOperationQueue使用currentQueue,而不是mainQueue. Apple建议它不在mainQueue上运行,但是如果您的应用程序当前正在主队列中运行,那么我不会看到currentQueue有何不同.我尝试使用GCD将下面的代码移动到不同的队列,但是没有调用任何代码.

以下是您的最终代码应如下所示:

  1. // Check if Motion / Location services are available
  2. if (motionManager.deviceMotionAvailable == YES && motionManager.accelerometerAvailable == YES) {
  3. NSLog(@"Away we go");
  4. self.MManager.deviceMotionUpdateInterval = 10.0/60.0;
  5. [self.MManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMDeviceMotion *motion,motion.userAcceleration.y);
  6. }];
  7. } else {
  8. // Motion / Accelerometer services unavailable
  9. }

我还应该注意,你创建CMMotionManager属性(据我所知)是正确的(强,非原子).

猜你在找的iOS相关文章