Как сохранить NSTimer в живых? - PullRequest
0 голосов
/ 20 марта 2012

В моем приложении 2 viewController, от первого вида, когда я перехожу к следующему, есть кнопка с именем startTimer с действием таймера в качестве метода выбора при нажатии на startTimer таймер запускается в ЧЧ: мм: сс формат, я не отменяю таймер, но когда я возвращаюсь к 1-му viewController и снова, если я возвращаюсь ко 2-му viewController и если я нажимаю кнопку startTimer, таймер снова начинается с 0, но я хочу, чтобы он был сохранен предыдущим значение, как я могу этого достичь? я знаю, что, поскольку я снова загружаю viewController, перо будет загружено в память только что, но как я могу сохранить метку таймера и значение таймера? Любая помощь приветствуется. Спасибо.

Ответы [ 4 ]

3 голосов
/ 20 марта 2012

Вы нарушили MVC (Model-View-Controller), поместив свои данные в свой контроллер представления.Более того, вы просите механизм без твердых обещаний о времени (NSTimer), чтобы отслеживать время для вас.NSTimer не запускает точно в интервале, который вы запрашиваете.Он может стрелять в любой произвольной точке после этого интервала. Использование NSTimer в качестве секундомера почти всегда будет терять время (иногда довольно много времени, особенно при наличии прокрутки). (Этот последний бит завышен. Повторяющийся таймер правильно планирует себя, поэтому победил 'обычно теряет время. Вы просто потеряете время, если повторение будет полностью пропущено, что может произойти во время длинных прокруток или других вещей, которые могут удерживать таймеры для срабатывания в течение полной секунды.)

Создание нового объекта моделихранить информацию о секундомере.Давайте назовем это Stopwatch.Предполагая, что вам нужно, чтобы он был запускаемым и останавливаемым, ему нужны свойство NSTimeInterval accumulatedTime и свойство NSDate lastStarted (вы также можете сделать lastStarted NSTimeInterval, если хотите).Таким образом, чтобы запустить секундомер, вы установите lastStarted на «сейчас».Чтобы остановить секундомер, вы очищаете lastStarted и перемещаете текущее накопленное время в accumulatedTime.Чтобы узнать текущее время, вы добавляете accumulatedTime к now - lastStarted.

ОК, теперь, когда у вас есть это, что вы можете с ним сделать?Вы можете передать его своим контроллерам представления, и они могут спросить "каково текущее значение секундомера?"Они могут запускать и останавливать его по своему усмотрению.

Теперь ваш контроллер представления хотел бы обновлять свой дисплей каждую секунду, поэтому у вас есть таймер, который делает это.Каждую секунду он спрашивает секундомер «каково текущее время» и отображает его.Но он не устанавливает время.Он просто спрашивает.

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

0 голосов
/ 20 марта 2012

Что бы я сделал, это поддержал бы второй контроллер вида в качестве ивара вашего первого контроллера вида.Таким образом, вы можете создать его экземпляр только один раз, и ваш NSTimer останется в памяти.

Однако, если вы хотите сохранить свой стиль, вам следует сохранить текущее время в любых предпочтениях (см. [NSUserDefaults standardUserDefaults]или создайте свой собственный класс синглтона).Затем в view загрузил метод из вашего второго контроллера представления, загрузите это значение и добавьте его в качестве смещения для вашего таймера.

Надеюсь на помощь!

0 голосов
/ 20 марта 2012

Если NSTimer - одна из переменных вашего экземпляра, я думаю, вы могли бы проверить, выделен ли он или нет.


//NSTimer *timer;  declare this in your interface

if (timer==nil)
{
   // allocate timer
}
//Do nothing if it is allocated all ready

0 голосов
/ 20 марта 2012

Не делайте так, каждый раз, когда вы загружаете представление, содержащее NSTimer, создается новый объект NSTimer, а старый остается в памяти, поскольку вы его не аннулируете.

Лучший способ заключается в том, что вы должны поместить NSTimer в Application Delegate, а затем запустить его только при первой загрузке этого View Controller.

Для достижения этого вы должны установить флаг, чтобы убедиться, что View загруженв первый раз или нет.

...