8

我编写了一个应用程序来测试 iOS 上的图像性能。我尝试了 3 种不同的视图,都显示相同的大 PNG。第一个是使用 CGContextDrawImage() 绘制的视图。第二个设置 self.layer.content。第三个是一个普通的 UIImageView。

使用的图像使用 -[UIImage initWithContentsOfData:] 创建并缓存在 viewController 中。每个测试重复分配一个视图,将其添加到视图层次结构中,然后将其删除并释放它。从 loadView 开始到 viewDidAppear 的时间以 fps 的形式给出(实际上是每秒视图绘制)。

以下是运行 5.1 的 iPad 1 使用 912 x 634 未缩放图像的结果:

CGContext:    11 fps
CALayer:      10 fps
UIImageView: 430 fps (!)

我产生幻觉了吗?UIImageView 几乎不可能画得那么快,但我实际上可以看到图像闪烁。我尝试在两个相似的视图之间交换以阻止可能的缓存,但帧速率甚至更高。

我一直认为 UIImageView 只是 -[CALayer setContent] 的包装器。但是,分析 UIImageView 显示几乎没有时间花在我可以识别的任何绘图方法上。

我很想了解发生了什么。非常感激任何的帮助。

4

3 回答 3

1

这是我的想法。

当您通过添加、删除或修改某些视图来修改 UIView 层次结构时,还没有执行实际的绘制。相反,视图被标记为“setNeedsDisplay”,并在下次运行循环可以自由绘制时重新绘制。

事实上,如果您的测试代码看起来像这样(我只能猜测):

for (int i=0; i<10000; i++) {
     UIImageView* imageView = [[UIImageView alloc] initWithFrame:frame];
     [mainView addSubview: imageView];
     [imageView setImage: image];
     [mainView removeSubview: imageView];
}

在这个 for 循环完成之前,runloop 会被阻塞。视图层次结构只绘制一次,测量的性能是分配和初始化对象的性能。

另一方面,我认为 CGContextDrawImage() 可以立即自由绘制。

于 2012-04-19T06:06:32.533 回答
1

UIImageView 的高 FpS 是因为这实际上并没有重绘,而只是在将来 UIKit 想做的时候标记内容以供重绘。

注意:奇怪的是,CGContext 方法比 CALayer 方法快。我还在我的一个项目中尝试了这些方法,使用 CALayer 是最快的方法(当然使用 OpenGL ES 除外)。

于 2012-11-12T13:01:31.030 回答
0

UIImageView 使用一种不同的方式来渲染图像,这种方式效率更高。您应该观看 WWDC 2011 的此会话视频,该视频解释了渲染过程的工作原理:https ://developer.apple.com/videos/wwdc/2011/?id=121

于 2012-05-04T13:57:09.747 回答