我正在尝试在常规(非 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 的文章,但没有找到描述我的问题的人。我发现的最接近的是在这个问题中
请记住,如果 CADisplayLink 无法触发屏幕刷新(由于主线程忙于绘制前一帧之类的事情),那么它可能会跳过它,因为它没有足够的时间来完成。
不过,我似乎在官方文档中找不到任何证据,希望我做错了什么......
如果有任何区别,则有问题的设备正在运行 iOS 4.3.3。