NSTimer и акселерометр в iPhone / iPad - PullRequest
2 голосов
/ 24 сентября 2010

У меня есть требование в моем приложении, которое требует от меня отображения некоторого сообщения пользователю, если в приложении / ipad в течение 3 часов не происходит никаких действий. Я подумал о том, чтобы иметь NSTimer, который запускается при запуске. Если пользователь выполняет какое-либо действие, я отменяю таймер и запускаю новый. Тем не менее, в приложении воспроизводится видео, и, насколько мне известно, пользователь может смотреть видео в течение примерно 3 часов, не предпринимая никаких других действий в течение этого времени и все равно получит сообщение.

Итак, альтернативой является отключение и запуск таймера при каждом обнаружении перемещения ipad / iphone. Другими словами, используйте акселерометр и при обратном вызове, чтобы обнаружить ускорение, я могу сделать недействительным и снова создать таймер. Но меня беспокоит такой подход, что даже для самых маленьких движений таймер должен быть аннулирован и воссоздан. Повлияет ли этот подход на производительность?

Спасибо и С уважением, Hetal

Ответы [ 3 ]

0 голосов
/ 25 сентября 2010

Создание таймера не , что дорого, но все же немного дороже.

Хорошей новостью является то, что вы можете произвольно изменить дату пожара:

[timer setFireDate:[NSDate dateWithTimeIntervalSinceNow:3*60*60]];

В качестве альтернативы для очень незначительно меньше накладных расходов:

CFRunLoopTimerSetNextFireDate((CFRunLoopTimerRef)timer, CFAbsoluteTimeGetCurrent()+3*60*60);

(Я думаю, что издержки CFAbsoluteTimeGetCurrent () - это больше, чем накладные расходы на создание объекта, но не так.)

Несколько лучшим решением может быть то, что большую часть времени вы оставляете таймер в покое; просто обновите отметку времени «последней активности». Когда таймер срабатывает, посмотрите на отметку времени «последней активности». Если прошло более 3 часов назад, покажите уведомление. Если это менее 3 часов назад, то установите соответствующую дату следующего пожара; это означает, что таймер срабатывает (в среднем) не чаще, чем каждые 1,5 часа, что , вероятно, не так дорого, как многократное изменение даты запуска.

См. mach_absolute_time() относительно низкой временной задержки (предварительный расчет 3 часов в единицах mach_absolute_time). Это по-прежнему занимает около 3 микросекунд, что практически навсегда (1000 тактов!).

Если вы действительно беспокоитесь о накладных расходах, просто устанавливайте флаг "активность" каждый раз, когда что-то происходит, и используйте (например,) таймер на 1 час. Когда таймер срабатывает, сделайте что-то вроде if (activity) {counter = 0; activity = 0; } else { counter ++; if (counter == 3) { ... } }. Это спорный вопрос, является ли пара микросекунд здесь и там являются более дорогостоящими, чем таймер стрельбы каждый час, но они оба довольно незначительны.

Гораздо большая проблема заключается в том, что акселерометр потребляет энергию и время процессора (а доставка обновлений занимает время процессора). Установка updateInterval = 10 или около того уменьшит накладные расходы, и ОС ограничит их до разумного значения (около 1 с).

0 голосов
/ 25 сентября 2010

Разве вы не можете просто отправить сообщение вашему NSTimer всякий раз, когда начинается видео, чтобы сделать таймер недействительным?Затем, когда фильм закончится, запустите таймер.

0 голосов
/ 24 сентября 2010

У Apple есть функция многозадачности, которую они называют «Завершение задачи», используя - (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void(^)(void))handler Найдено здесь и другие вещи здесь

...