如何正确停止和恢复CADisplayLink? [英] How to correctly stop and resume a CADisplayLink?

查看:223
本文介绍了如何正确停止和恢复CADisplayLink?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现CADisplayLink存在一个大问题.

I figured out a big problem with CADisplayLink.

我拥有最基本的EAGLLayer和OpenGL ES 1.1,它绘制了一个旋转三角形进行测试.这需要以屏幕刷新率调用运行循环方法,因此我像这样启动运行循环:

I have the most basic EAGLLayer with OpenGL ES 1.1 drawing a rotating triangle for testing. This needs a run loop method to be called at screen refresh rate, so I start the runloop like this:

- (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.依此类推.乒乓球.

When the test app launches, I call -startRunloop. When I tap the screen, I call -stopRunloop. When I tap again, I call -startRunloop. And so forth. Ping Pong.

我正在测量-drawFrame方法在20秒内被调用的频率,并记录它.

I'm measuring how often the -drawFrame method is called in 20 seconds, and NSLog it.

  • 第一个开始/停止周期始终以100%执行.我得到了最大帧速率.

  • The FIRST start / stop cycle always performs at 100%. I get the maximum frame rate.

所有随后的开始/停止周期仅显示大约80%的性能.我得到了明显较小的帧速率.但是:总是几乎完全相同,+/-2帧.即使再经过50个启动/停止周期,也没有进一步降低的趋势.

All SUBSEQUENT start / stop cycles only show about 80% of the performance. I get a significantly smaller frame rate. But: Always almost exactly the same, +/- 2 frames. With no tendency to degrade further even after 50 more start / stop cycles.

结论:像我上面所做的那样创建CADisplayLink很好,直到它无效或暂停为止.之后,任何新的CADisplayLink都将无法正常运行.即使它是新创建的,也和以前完全一样.如果我通过使用-是/否调用-setPaused:方法来暂停/恢复它,也是如此.

In conclusion: CREATING a CADisplayLink like I do above is fine, until it's invalidated or paused. After that, any new CADisplayLink does not perform well anymore. Even if it's created new and in the exact same way as before. Same is true if I pause / resume it by calling the -setPaused: method with YES / NO.

我已使用分配和VM Tracker Instruments确保没有内存管理问题.我还检查了是否确实调用了CADisplayLink的-invalidate方法.

I've made sure with Allocations and VM Tracker Instruments that there is no memory management issue. I've also checked that the -invalidate method of CADisplayLink really gets called.

设备(iPhone 4)上的iOS 4.0.

iOS 4.0 on the device (iPhone 4).

那是为什么?我想念什么吗?

Why is that? Am I missing something?

推荐答案

我认为您真正想要的只是暂停和取消暂停显示链接.

I think you what you really want is simply to pause and unpause your display link.

 - (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;
}

这篇关于如何正确停止和恢复CADisplayLink?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆