跟踪UIScrollView时,每个帧都没有执行带有NSRunLoopCommonModes的CADisplayLink?

时间:2012-02-05 18:22:08

标签: iphone uiscrollview uikit tracking cadisplaylink

我正在尝试在常规(非OpenGL)iPhone应用程序中的每一帧上执行一小段代码。目标是拥有一个帧计数器,以便我可以测量(而不是猜测)应用程序中的慢点,并修复它们以创建更好的用户体验。

到目前为止我所做的是为所有模式(包括跟踪)注册CADisplayLink:

CADisplayLink *displayLink = [[CADisplayLink displayLinkWithTarget:self selector:@selector(frame)] retain];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];

执行的代码如下所示(lastDraw是NSDate *并计算为int):

- (void) frame {
NSDate *newDate = [NSDate date];

if([newDate timeIntervalSinceDate:lastDraw] >= 1) {
    label.text = [NSString stringWithFormat:@"%d FPS", count];

    count = 0;
    [lastDraw release];
    lastDraw = [newDate retain];
}

count++;
}

这里的想法是每隔一秒获得一次更新,了解在过去的第二帧中绘制了多少帧。

这似乎工作正常,但在UIScrollView中滚动时数字肯定是关闭的:如果我只是像普通人一样滚动,那么帧速率似乎有意义。但是,如果我上下剧烈滚动,那么显示的速率会下降到1或2 fps,但显然有更多的帧被绘制而不是每秒一帧。

当我改变这样的帧方法时:

- (void) frame {
    label.text = [NSString stringWithFormat:@"%f", displayLink.timestamp];
}

很明显,滚动时会触发很少的事件。

我在这里和网上阅读了很多文章,这些文章涉及UIScrollViews和NSRunLoopCommonModes与NSDefaultRunLoopMode,但没有找到描述我问题的人。我找到的最接近的是question

  

请记住,如果CADisplayLink无法触发屏幕刷新(由于主线程忙于处理绘制前一帧),那么它可能会跳过它,因为它没有足够的时间来完成。 / p>

我似乎无法在官方documentation找到任何证据,并希望我做错了...

如果它有任何区别,有问题的设备正在运行iOS 4.3.3。

1 个答案:

答案 0 :(得分:1)

我在http://bugreport.apple.com/的机票#10848893中用Apple验证了这一点,看来它确实是iOS 5.1种子3中修复的错误,我无法重现该问题。