如何正确停止和恢复CADisplayLink?

时间:2011-12-07 02:22:47

标签: iphone ios performance cadisplaylink

我发现了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)。

为什么?我错过了什么吗?

5 个答案:

答案 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)