Search code examples
iosmultithreadinggrand-central-dispatchnsoperationqueuecore-motion

What If the Updates Handler for CoreMotion Does Not Finish Fast Enough?


I am registering to receive updates from a CMMotionManager like so:

motionManager.startDeviceMotionUpdatesToQueue(deviceMotionQueue) {
    [unowned self] (deviceMotion, error) -> Void in

    // ... handle data ...
}

where deviceMotionQueue is an NSOperationQueue with the highest quality of service, i.e. the highest possible update rate:

self.deviceMotionQueue.qualityOfService = NSQualityOfService.UserInteractive

This means that I am getting updates often. Like really often. So I was wondering: what happens if I don't handle one update fast enough? If the update interval is shorter than the execution time of 'handle data'? Will the motion manager drop some information? Or will it queue up and after a while become run out of memory? Or is this not feasable at all?


Solution

  • It's hard to know what the internal CoreMotion implementation will do, and given that what it does is an "implementation detail", even if you could discern its current behavior, you wouldn't want to rely on that behavior moving forward.

    I think the common solution to this is to do the minimum amount of work in the motion update handler, and then manage the work/rate-limiting/etc yourself. So, for instance, if you wanted to drop interstitial updates that arrived while you were processing the last update, you could have the update handler that you pass into CoreMotion do nothing but (safely) add a copy of deviceMotion to a mutable array, and then enqueue the "real" handler on a different queue. The real handler might then have a decision tree like:

    • if the array is empty, return immediately
    • otherwise (safely) take the last element, clear all elements from the array, and do the work based on the last element

    This would have the effect of letting you take only the most recent reading, but also to have knowledge of how many updates were missed, and, if it's useful, what those missed updates were. Depending on your app, it might be useful to batch process the missed events as a group.

    But the takeaway is this: if you want to be sure about how a system like this behaves, you have to manage it yourself.