我发现了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它。
FIRST启动/停止循环始终执行100%。我得到了最大帧速率。
所有SUBSEQUENT开始/停止周期仅显示约80%的性能。我的帧速率要小得多。但是:总是几乎完全相同,+ / - 2帧。即使再经过50次启动/停止循环,也不会有进一步降级的倾向。
总之:像我上面那样创建CADisplayLink很好,直到它失效或暂停。之后,任何新的CADisplayLink都不再表现良好。即使它是以与以前完全相同的方式创建的。如果我通过使用YES / NO。
调用-setPaused:方法暂停/恢复它也是如此我已经确定Allocations和VM Tracker Instruments没有内存管理问题。我还检查过CADisplayLink的-invalidate方法是否真的被调用。
设备上的iOS 4.0(iPhone 4)。
为什么?我错过了什么吗?
答案 0 :(得分:8)
我认为您真正想要的只是暂停和取消暂停显示链接。
- (void)createRunloop {
CADisplayLink *dl = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(drawFrame)];
[dl setFrameInterval:1.0];
[dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
self.displayLink = dl;
// start in running state, your choice.
dl.paused = NO;
}
- (void)startRunloop {
self.displayLink.paused = NO;
}
- (void)stopRunloop {
self.displayLink.paused = YES;
}
- (void)destroyRunloop {
[self.displayLink invalidate];
self.displayLink = nil;
}
答案 1 :(得分:5)
我正在使用
[displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
看看它是否适合你
答案 2 :(得分:3)
对于Swift 4.2
displayLink.remove(from: RunLoop.current, forMode: RunLoop.Mode.common)
答案 3 :(得分:1)
您可以在每次启动调用时创建一个新的显示链接实例。您是否尝试过重复使用同一个实例?
此外,您可以随时暂停显示链接。
答案 4 :(得分:0)
在Swift中尝试这个,
displayLink?.remove(from: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)