Я выяснил большую проблему с CADisplayLink.
У меня есть самый простой EAGLLayer с OpenGL ES 1.1, рисующий вращающийся треугольник для тестирования. Для этого необходимо вызвать метод цикла выполнения с частотой обновления экрана, поэтому я запускаю цикл запуска следующим образом:
- (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.
ПЕРВЫЙ цикл пуска / останова всегда выполняется при 100%. Я получаю максимальную частоту кадров.
Все последующие циклы пуска / останова показывают только около 80% производительности. Я получаю значительно меньшую частоту кадров. Но: всегда почти одинаково, +/- 2 кадра. Без тенденции к дальнейшему ухудшению даже после 50 дополнительных циклов пуска / останова.
В заключение: СОЗДАТЬ CADisplayLink, как я делал выше, хорошо, пока он не будет аннулирован или приостановлен. После этого любой новый CADisplayLink перестает работать хорошо. Даже если он создан новым и точно так же, как и раньше. То же самое верно, если я приостановлю / возобновлю его, вызвав метод -setPaused: с YES / NO.
С помощью Allocations и VM Tracker Instruments я убедился, что нет проблем с управлением памятью. Я также проверил, что -advalidate метод CADisplayLink действительно вызывается.
iOS 4.0 на устройстве (iPhone 4).
Почему это? Я что-то упустил?