In my root controller I have a property with the CMMotionManager
@property (strong, nonatomic) CMMotionManager *MManager;
In i
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)
.