I get OSSpinLockLock when calling startDeviceMotionUpdatesToQueue inside a controller

前端 未结 1 1724
星月不相逢
星月不相逢 2021-01-12 10:52

In my root controller I have a property with the CMMotionManager

@property (strong, nonatomic) CMMotionManager *MManager;

In i

相关标签:
1条回答
  • 2021-01-12 11:23

    I was trying to do something similar in my iOS app and spent forever trying to figure out what the cause of the crash was. This was a very cryptic (and pesky) exception. I eventually figured it out after reading through the crash reports that OSSpinLock has to do with a thread / queue management issue.

    The NSOperationQueue is the culprit here. Your code doesn't show how you were creating your NSOperationQueue, but I assume it was something like this:

    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);
    }];
    

    It turns out that this is not the way to use the NSOperationQueue. That aQueue object is the cause of the crash.

    To properly setup the operation queue and avoid a crash, you should move your CMMotionManager to a different thread. Then tell NSOperationQueue to use the currentQueue, NOT the mainQueue. Apple recommends that it is not run on the mainQueue, however if your app is currently running in the main queue then I don't see how the currentQueue is any different. I tried moving the code below to a different queue using GCD, but no code was ever called.

    Here's what your final code should look like:

    // 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
    }
    

    I should also note that your creation of the CMMotionManager property (to my knowledge) is correct with (strong, nonatomic).

    0 讨论(0)
提交回复
热议问题