我发现了 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 它。
FIRST 启动/停止循环始终以 100% 执行。我得到最大帧速率。
所有 SUBSEQUENT 启动/停止循环仅显示大约 80% 的性能。我得到一个明显更小的帧速率。但是:总是几乎完全相同,+/- 2 帧。即使在 50 多个启动/停止循环之后,也没有进一步退化的趋势。
总之:像我上面那样创建一个 CADisplayLink 很好,直到它失效或暂停。之后,任何新的 CADisplayLink 都不再表现良好。即使它是新的并且以与以前完全相同的方式创建。如果我通过使用 YES/NO 调用 -setPaused: 方法来暂停/恢复它,情况也是如此。
我已经通过 Allocations 和 VM Tracker Instruments 确保没有内存管理问题。我还检查了 CADisplayLink 的 -invalidate 方法是否真的被调用了。
设备上的 iOS 4.0 (iPhone 4)。
这是为什么?我错过了什么吗?