我正在尝试在常规(非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,但很明显,绘制的帧多于每秒一帧。

当我像这样更改frame方法时:

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


显而易见,滚动时几乎不会触发任何事件。

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


  请记住,如果CADisplayLink无法触发以刷新屏幕(由于主线程正忙于绘制前一帧之类的事情),则它可能会跳过它,因为它没有足够的时间来完成。


不过,我似乎在官方documentation中找不到任何证据,希望我做错了什么...

如果有任何区别,则所讨论的设备运行的是iOS 4.3.3。

最佳答案

我在http://bugreport.apple.com/的票证#10848893中与Apple进行了验证,似乎确实是iOS 5.1种子3中修复的错误,在该错误中我无法重现此问题。

10-08 15:44