Я понял большую проблему с CADisplayLink.
У меня есть самый простой EAGLLayer с OpenGL ES 1.1, рисующий вращающийся треугольник для тестирования. Для этого требуется метод цикла выполнения, который вызывается при частоте обновления экрана, поэтому я запускаю runloop следующим образом:
- (void)startRunloop {
if (!animating) {
CADisplayLink *dl = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(drawFrame)];
[dl setFrameInterval:1.0];
[dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
self.displayLink = dl;
animating = YES;
}
}
- (void)stopRunloop {
if (animating) {
[self.displayLink invalidate];
self.displayLink = nil;
animating = NO;
}
}
Когда запускается тестовое приложение, я вызываю -startRunloop. Когда я нажимаю экран, я вызываю -stopRunloop. Когда я снова нажимаю, я вызываю -STARTRunloop. И так далее. Пинг-понг.
Я измеряю, как часто вызывается метод -drawFrame через 20 секунд, и NSLog it.
-
ПЕРВЫЙ цикл запуска/остановки всегда выполняется на 100%. Я получаю максимальную частоту кадров.
-
Все циклы запуска/остановки SUBSEQUENT показывают только около 80% производительности. Я получаю значительно меньшую частоту кадров. Но: всегда почти то же самое, +/- 2 кадра. Без тенденции к дальнейшему ухудшению даже после еще 50 циклов старта/остановки.
В заключение: СОЗДАНИЕ CADisplayLink, как я делаю выше, в порядке, пока он не будет признан недействительным или приостановлен. После этого любой новый CADisplayLink больше не работает. Даже если он создал новый и точно так же, как раньше. То же самое верно, если я приостанавливаю/возобновляю его, вызывая метод -setPaused: с YES/NO.
Я уверен, что с Allocations и VM Tracker Instruments нет проблемы с управлением памятью. Я также проверил, что метод -invalidate CADisplayLink действительно вызван.
iOS 4.0 на устройстве (iPhone 4).
Почему? Я что-то пропустил?