ios updateDisplay по таймеру

У меня есть несколько сложный пользовательский интерфейс iOS, где мне нужно перезагружать определенную ячейку UICollectionView каждую секунду, чтобы показать время (вроде сложного секундомера), мне также нужно делать несколько других вещей каждую секунду в этом вызове,

Часть 1 вопроса


Мой вопрос: какова наилучшая практика для решения этого типа проблемы?

Вариант 1 (использовать рекурсивный вызов)

- (void)viewDidLoad
{
   [self runUpdateDisplayLoop];
}
- (void)runUpdateDisplayLoop
{
   //do stuff (reload cell, etc)

   //Recurissively Call Every Second
    dispatch_async(dispatch_get_main_queue(), ^{

        [self performSelector:@selector(runUpdateDisplayLoop) withObject:nil afterDelay:1.0];

    });
}

Вариант 2 (использовать NSTimer)

- (void)viewDidLoad
{
   NSTimer *updateDisplayTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                              target:self 
                                            selector:@selector(runUpdateDisplayLoop:) 
                                            userInfo:nil 
                                             repeats:YES];
}

- (void)updateDisplayLoop:(NSTimer *) theTimer
{
 //do stuff (reload cell, etc)
}

Часть 2 вопроса


В любом случае, что является лучшим местом для начала и завершения этих циклов?

Если я помещу их в ViewDidLoad, они будут продолжать вызываться, даже когда я ушел от соответствующего представления, я бы предпочел запускать цикл только тогда, когда это необходимо. С другой стороны, цикл должен выполняться каждый раз, когда отображается представление (даже если представление было отклонено различными способами - приложение закрыто и вновь открыто, прерывание телефонного звонка и т. Д.). Что касается жизненного цикла приложения, я нацеливаюсь на iOS 5 и iOS 6.

Я предполагаю, что есть решение, включающее "viewWillAppear" и "viewWillDisappear", но я опасаюсь попадания в ситуации, когда один или другой не вызывается. Я также не хочу создавать несколько циклов, делая какие-либо ложные предположения.

2 ответа

Решение

Для части 1

Я рекомендую использовать таймер. Основная причина в том, что вы можете остановить процесс, сделав недействительным таймер. С помощью PerforSelector вы можете добиться чего-то подобного, но я бы не пошел по этому пути. Каждому свое.

Для части 2

Вы хотите использовать viewWillAppear (или же viewDidAppear) а также viewDidDisappear (или же viewWillDisappear). Установите таймер на появлении и снесите его на исчезнуть.

Проверьте RespondingtoDisplay-Уведомления

Надеюсь, что это проливает свет на вещи и решает ваши вопросы, но я опасаюсь попадать в ситуации, когда один или другой не вызван. беспокойство

В то время как NSTimer будет работать, он не предназначен для создания секундомеров и т.п. Вы не можете полагаться на то, что он стреляет каждую секунду, поэтому вам все равно придется использовать NSDate объект и что-то вроде timeIntervalSinceDate вычислить значение, отображаемое для таймера при каждом его срабатывании. Таким образом, ваш секундомер может наверстать упущенное, если он не срабатывает в течение одной или нескольких секунд.

События NSTimer обрабатываются главным циклом выполнения, и если основной цикл выполнения занят, события не запускаются.

Мне больше нравится идея фонового потока. Однако вам не нужна рекурсия, чтобы она работала.

Просто создайте пользовательский класс Timer с помощью start, calcTime (и, возможно, остановки, сброса и возобновления). Когда вы вызываете start, объект должен просто получить текущую дату / время (NSDate) и сохранить его. Когда вы вызываете calcTime, просто получите текущую дату / время снова, рассчитайте время, прошедшее с помощью timeIntervalSinceDateи либо вернуть значение, либо установить свойства, которые вы можете прочитать.

В фоновом потоке просто продолжайте вызывать calcTime метод и обновить интерфейс через dispatch_async(dispatch_get_main_que)(), а затем поспать около 100 миллисекунд между звонками. Вы можете проверить булеву глобальную переменную, чтобы увидеть, должны ли вы продолжать работать.

Фоновый поток все еще может зависнуть, если процессор подключен, однако, это менее вероятно, чем основной цикл выполнения, который занят, что отвечает за это.

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

Другие вопросы по тегам