设备运动更新的实际频率低于预期,但随设置增加而扩大。

12

我正在将一款最初在IOS 3上使用加速度计编写的应用程序进行移植,以融合新的IOS 4运动功能。

在捕捉运动时,该应用程序不会做其他事情-例如不进行图形更新。

为了设置运动更新作为之前使用加速度计的替代方案,我正在执行以下操作。我确实意识到我可以重新构建来使用NSTimer或其他方式进行自己的轮询,并可能继续追求这样做。

[motionManager setDeviceMotionUpdateInterval:updateInterval];
CMDeviceMotionHandler motionHandler = ^(CMDeviceMotion *motion, NSError *error) {
[self processMotion:motion withError:error];
};

[motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:motionHandler];

这很有效,但是更新间隔的行为并不如预期。我已经剥离了processMotion方法中除了保存时间戳以查看真实运动更新速率以外的所有执行代码。我已经测试过足够的次数,证明了它的可重复性,甚至1/40的奇怪结果也是如此。下表显示了我所看到的内容:

updateInterval  actual events per second
1.0/20.0        13
1.0/30.0        27
1.0/40.0        27
1.0/50.0        34
1.0/60.0        40
1.0/70.0        57
1.0/90.0        60
1.0/100.0      74

一些注意事项:
1. 我确信已经正确设置了更新间隔,并在设置后进行了检查确认。

2. 我确定我正在跟踪每个processMotion的调用,没有使用nil CMDeviceMotion或其他奇怪情况。

3. 我没有进行任何会阻塞进程的重要处理,只是等待运动事件并记录它们。这在作为加速度计的委托时完全正常工作。

4. 运动数据不错,只是更新频率太低了 :) 5. 这是在第四代iPod touch上使用iOS 4.2。 6. 我已经尽力搜索,没有看到解释,但我看到一些人在请求60Hz时看到50Hz的更新频率,这可能与此有关。下一步我将尝试设置一个专门的队列来进行处理,而不是使用当前队列,但我想知道这是否是已知的行为。如果更新速率被某种方式限制,我可以理解,但如果是这种情况,不确定为什么它仍然会像所示那样增加。再次强调,我也可以重建使用NSTimer并进行自己的轮询,但我想了解为什么我看到这个问题,以防我基本上误解了Core Motion框架。

我用类似的方法在iPhone 4上也发现了这个问题。看起来CoreMotion仍然存在一些bug。 - Kay
谢谢留言,也许我会使用1/90并在时间戳显示速率符合预期时更改为1/60...虽然这是个不太正规的方法。 - J.Spiral
2
这只是一个快速的更新,我改用由NSTimer驱动的轮询,结果通常更好,但有时会出现连续两次获取相同的样本值。我会继续尝试实验。 - J.Spiral
4天前您的回复被错过了。这可能是一种竞争条件问题,如果计时器比核心运动更快,尤其是当核心运动未按预期传递事件时。 - Kay
是的,不过这种情况相对较少,而且由于我可以随时检查时间戳,所以对我来说还好。未来是否会有所改善或者出现新的信息将会很有趣。 - J.Spiral
1个回答

3

好的,这里有一个可能的解决方案:

NSOperationQueue 上并发操作的数量由操作系统确定。这意味着有时可能只有很少甚至只有1个操作在同时进行。

您可以明确地设置操作数为某个合理的数字,例如:

[operationQueue setMaxConcurrentOperationCount:5];

祝你愉快。


非常有趣。我已经很久以前就离开了那个项目,也没有一个开发环境方便快速测试,但似乎人们偶尔会检查这个。如果有几个人想要确认这一点,我会接受的,否则就得等到我有时间设置自己的测试。 - J.Spiral
嘿,J.Spiral,我的回答有帮到你吗?你从来没有回复。 :) - Usman.3D
1
抱歉,让你等了这么久! - J.Spiral

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接