2015-04-29 2 views
1

Код обработчика (в данном случае, сбор данных акселерометра) выполняется асинхронно, когда мой акселерометр перемещается.Как сохранить данные, которые производятся в обработчике?

Это означает, что, если я пытаюсь сохранить data.x, data.y, data.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) 
    } 
+0

Можете ли вы разместить часть своего кода? – ABakerSmith

+0

Да! Обычно я считаю проблему более концептуальной, а не на уровне кода (которая, как правило, обфускает вещи), но иногда код помогает проиллюстрировать пример! Просто отправил короткую функцию. Я хочу сохранить grav.x. – Aspen

+1

Возможно, вам нужно будет сохранить данные в некотором свойстве и вызвать некоторую функцию (или опубликовать уведомление) о том, что есть данные для обработки. Именно то, что вы принимаете, зависит от того, что вы хотите делать с данными. скажем, вы хотели обновить сюжет с новыми данными - вы могли бы вызвать функцию с чтением, которое добавило данные в свойство массива и обновил график. Если вы хотите озвучить предупреждение, если показания были выше некоторого порога, вы можете вызвать функцию, которая просто сравнивала значение, воспроизводила звук, если это необходимо, а затем отбрасывать показания. – Paulw11

ответ

1

Главное, чтобы быть осторожными в том, что эти события могут прийти быстрее, чем основной поток может обрабатывать их. Как указано в документации:

Поскольку обработанные события могут достигать высокой скорости, использование основной очереди операций не рекомендуется.

Следовательно, для обработки этих событий вы должны использовать свою собственную фоновую очередь.

Что касается, как вы затем использовать эту обновленную информацию о главном потоке, есть два соображения:

  1. Чтобы обеспечить код потокобезопасно, любые переменные, которые вы используете как из этого фонового потока и других потоки должны быть синхронизированы.

  2. Удостоверьтесь, что вы не просто отправляете обновления обратно в основную нить. Обычно я создавал бы источник отправки DISPATCH_SOURCE_TYPE_DATA_OR или DISPATCH_SOURCE_TYPE_DATA_ADD, помещал обработчик для этого источника в основную очередь, а затем ваш motionQueue затем мог бы выполнить dispatch_source_merge_data на этом источнике.

    GCD затем объединяет эти изменения данных, уведомляя основной поток о наличии обновлений, но не забывая о главном потоке процесса.


Кстати, вы также можете просмотреть Таблица 4-1 из Event Handling Guide, в котором излагаются общие интервалы обновления для ускорения событий (измеряется в Гц), в зависимости от предполагаемого использования:

  • 10-20: Подходит для определения вектора текущей ориентации устройства.

  • 30-60: подходит для игр и других приложений, которые используют акселерометр для ввода в реальном времени пользователя.

  • 70-100: подходит для приложений, которым необходимо определить высокочастотное движение. Например, вы можете использовать этот интервал, чтобы обнаружить, как пользователь наносит удар по устройству или быстро встряхивает его.

Вы можете выбрать deviceMotionUpdateInterval соизмеримы с потребностями вашего приложения.

Смежные вопросы