如何保存处理程序中生成的数据?

How do you save data that is being produced in a handler?

处理程序代码(在本例中为收集加速度计数据)在我的加速度计移动时异步执行。

这意味着如果我尝试将 data.xdata.ydata.z 保存在一个变量中,即使该变量是在处理程序外部声明的,该变量也将是 nil 如果我尝试在任何地方打印它。

如何保存此数据以便在我的代码的其他部分访问? (或者一切都必须在我的处理程序中发生,最佳实践明智吗?)

    if motionManager.accelerometerAvailable{
                    let motionQueue = NSOperationQueue.mainQueue()
                    motionManager.startDeviceMotionUpdatesToQueue(motionQueue,
                    withHandler: gravityUpdated)
    }
 func gravityUpdated(motion: CMDeviceMotion!, error: NSError!) {
        let grav : CMAcceleration = motion.gravity;
        println(grav.x)
  }

主要要警惕的是,这些事件进入的速度可能快于主线程处理它们的速度。正如文档所说:

Because the processed events might arrive at a high rate, using the main operation queue is not recommended.

因此,您应该自己的后台队列来处理这些事件。

关于如何在主线程上使用这个更新的信息,有两个考虑因素:

  1. 为确保您的代码是线程安全的,您在此后台线程和其他线程中使用的任何变量都必须同步。

  2. 确保您不只是将更新分派回主线程。我通常会创建 DISPATCH_SOURCE_TYPE_DATA_ORDISPATCH_SOURCE_TYPE_DATA_ADD 的调度源,将该源的处理程序放在主队列中,然后您的 motionQueue 可以执行 dispatch_source_merge_data这个来源。

    然后 GCD 将合并这些数据更改,在有更新时通知主线程,但不会在进程中积压主线程。


顺便说一句,您可能还想查看 Event Handling Guide 的 Table 4-1,其中概述了加速事件的常见更新间隔(以 Hz 为单位),具体取决于预期用途:

  • 10–20: Suitable for determining a device’s current orientation vector.

  • 30–60: Suitable for games and other apps that use the accelerometer for real-time user input.

  • 70–100: Suitable for apps that need to detect high-frequency motion. For example, you might use this interval to detect the user hitting the device or shaking it very quickly.

您可能希望选择 deviceMotionUpdateInterval 与您的应用需求相称的。