проблема iPhone NSTimer OpenGL - PullRequest
0 голосов
/ 07 мая 2010

У меня проблема, которая возникает только на устройстве, а не в симуляторе.

Анимация моего приложения запускается и останавливается с помощью следующих методов:

NSTimer* animationTimer;

-(void)startAnimation
{
    if(animationTimer == nil)
        animationTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f/60.0f target:self selector:@selector(drawView) userInfo:nil repeats:YES];
}

-(void)stopAnimation
{
    [animationTimer invalidate];
    animationTimer = nil;
}

В симуляторе это работает нормально, и drawView начинает вызываться со скоростью 60 кадров в секунду. На устройстве (тестирование на iPod Touch) метод scheduleTimerWithTimeInterval, похоже, не работает. Кроме того, [animationTimer invalidate] вызывает EXC_BAD_ACCESS.

Я заметил очевидный, но незначительный недостаток; добавление if (animationTimer! = nil) в метод stopAnimation предотвратит сбой, но не решит проблему неправильной инициализации таймера анимации.

Редактировать: Выше не предотвращает сбой. animationTimer! = ноль, но вызов недействительным вызывает EXC_BAD_ACCESS.

Следует также добавить, что эта проблема не возникает все время на устройстве. Может быть, 40% времени.

Ответы [ 2 ]

3 голосов
/ 08 мая 2010

Если animationTimer объявлено именно так, как вы показали, то его начальное значение не определено.Передача значения указателя, которое не соответствует выделенному объекту Objective-C, с большой вероятностью даст вам EXC_BAD_ACCESS.Вы должны явно установить его начальное значение на nil или рассмотреть возможность объявления его как переменной-члена вашего класса, чтобы при инициализации объекта оно было инициализировано равным 0 / nil с другими переменными-членами.

0 голосов
/ 07 мая 2010

Таймер не является механизмом реального времени; он срабатывает только тогда, когда работает один из режимов цикла выполнения, к которому был добавлен таймер, и может проверить, прошло ли время срабатывания таймера. Из-за различных входных источников, которыми управляет типичный цикл выполнения, эффективное разрешение временного интервала для таймера ограничено порядка 50-100 миллисекунд. Если время срабатывания таймера происходит во время длинного вызова или когда цикл выполнения находится в режиме, который не контролирует таймер, таймер не срабатывает до следующей проверки цикла таймером. Следовательно, фактическое время, в которое таймер срабатывает, потенциально может быть значительным периодом времени после запланированного времени срабатывания.

Имейте в виду, что NSTimer не всегда срабатывает "вовремя". Ваше приложение работает на симуляторе из-за огромного количества доступных ему ресурсов - практически весь процессор и доступная оперативная память на вашем Mac. Устройство, с другой стороны, имеет ограниченное количество доступных ресурсов. Это может привести к некоторому состоянию гонки в вашем приложении.

Другое дело, что вы не сохраняете таймер (что хорошо), поэтому единственный объект, который претендовал на владение им, это ваш текущий цикл выполнения. Когда вы звоните [таймер аннулировать]; таймер освобождается. Вполне возможно, что ваш таймер был освобожден где-то еще с помощью [timer invalidate]; функция. Попытка сделать недействительным уже недействительный таймер приведет к ошибке, которая соответствует вашему описанию.

В целом, ищите в своем коде другие места, где ваш таймер мог быть недействительным. Проверьте условия гонки тоже.

Надеюсь, это было полезно, Пол

...