CADisplayLink с NSRunLoopCommonMode не выполняется для каждого кадра при отслеживании UIScrollView? - PullRequest
2 голосов
/ 05 февраля 2012

Я пытаюсь выполнить небольшой фрагмент кода на каждом отдельном кадре в обычном (не OpenGL) приложении для iPhone. Цель состоит в том, чтобы иметь счетчик кадров, чтобы я мог измерить (а не угадать), где находятся медленные точки в приложении, и исправить их, чтобы улучшить взаимодействие с пользователем.

На данный момент я зарегистрировал CADisplayLink для всех режимов (включая отслеживание):

CADisplayLink *displayLink = [[CADisplayLink displayLinkWithTarget:self selector:@selector(frame)] retain];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];

Код, который выполняется, выглядит следующим образом (lastDraw является NSDate * и считается int):

- (void) frame {
NSDate *newDate = [NSDate date];

if([newDate timeIntervalSinceDate:lastDraw] >= 1) {
    label.text = [NSString stringWithFormat:@"%d FPS", count];

    count = 0;
    [lastDraw release];
    lastDraw = [newDate retain];
}

count++;
}

Идея состоит в том, чтобы каждую секунду получать обновления о том, сколько кадров было нарисовано за последнюю секунду.

Кажется, это работает нормально, но при прокрутке в UIScrollView цифры определенно не работают: если я просто прокручиваю как обычный человек, то частота кадров, кажется, имеет смысл. Однако, если я энергично прокручиваю вверх и вниз, то отображаемая скорость падает до 1 или 2 кадров в секунду, но ясно, что вырисовывается больше кадров, чем один раз в секунду.

Когда я меняю метод фрейма следующим образом:

- (void) frame {
    label.text = [NSString stringWithFormat:@"%f", displayLink.timestamp];
}

Становится очевидным, что при прокрутке происходит очень мало событий.

Я прочитал много статей здесь и в Интернете, которые имеют дело с UIScrollViews и NSRunLoopCommonModes против NSDefaultRunLoopMode, но не нашел кого-то, описывающего мою проблему. Самый близкий, который я нашел, был в этом вопросе

Помните, что если CADisplayLink не может запустить обновление экрана (из-за того, что основной поток занят такими вещами, как рисование предыдущего кадра), он может пропустить его, так как у него не будет достаточно времени для завершения.

Я не могу найти никаких доказательств этого в официальной документации , однако, и надеюсь, что я делаю что-то не так ...

Если есть какая-либо разница, то рассматриваемое устройство работает под управлением iOS 4.3.3.

1 Ответ

1 голос
/ 26 февраля 2012

Я проверил это с Apple в билете # 10848893 по номеру http://bugreport.apple.com/, и похоже, что это действительно ошибка, исправленная в iOS 5.1 seed 3, где я не могу воспроизвести проблему.

...