我发现了CADisplayLink的一个大问题。

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

- (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秒内被调用的频率,并记录它。
  • 第一个开始/停止周期始终以100%执行。我得到最大帧率。
  • 所有随后的开始/停止周期仅显示大约80%的性能。我得到了明显较小的帧速率。但是:总是几乎完全相同,+/-2帧。即使再经过50个启动/停止循环,也没有进一步降低的趋势。

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

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

    设备上的iOS 4.0(iPhone 4)。

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

    最佳答案

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

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

    10-04 23:46