Создание таймера не , что дорого, но все же немного дороже.
Хорошей новостью является то, что вы можете произвольно изменить дату пожара:
[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 с).