为什么这个CATiledLayer/PDF代码运行缓慢?

8

这是代码:

https://www.dropbox.com/s/o42wy36x4qhrbpt/PDFScroller.zip

我使用了WWDC 2010的PhotoScroller示例代码,该代码实现了嵌套的UIScrollViews用于缩放,在一个UIScrollView中用于分页,并替换了我认为仅需最少量的代码以显示多页PDF而不是图像。

它能正常工作。但是在我的iPhone4上速度很慢,大约需要三秒钟才能绘制第一页,甚至在我的iPod Touch上也更慢。我可以看到它正在绘制单个图块。这个相同的PDF在另一个使用简单的CATiledLayer/UIScrollView和触摸事件来更改页面的实现中已经更快地打开,没有可见的图块绘制。我想使用这个PhotoScroller技术,非常好。

我用Instruments中的CPU Sampler观察了它,似乎不是PDF渲染代码的问题,而是时间花费在线程和消息传递上。如果有人能帮助指出这个示例产生开销的原因,我会很感激。

谢谢,

Jim


更新1:我最初使用的是TilingView类技术,来自定义样本代码。

+ (Class) layerClass {
  return [CATiledLayer class];
}

然后在- (void)drawRect:(CGRect)rect中进行绘制,但是转而尝试使用显式的CATiledLayer子类以查看是否有所不同,但结果并没有改变,因此我将代码保留原样发布在这里。TilingView中还存在一个遗漏的[tiledLayer release];泄漏。


你找到解决方案了吗?我也在处理同样的问题。 - Anil Sivadas
是的,增加瓷砖大小可以显著提高性能。 - jbm
明白了,我刚在代码中添加了一行:tiledLayer.tileSize = CGSizeMake(512, 512); 运行得非常好!谢谢。 - Vibhor Goyal
3个回答

5

谢谢,这个真的很难找到。 - Dan Rosenstark

2
由于您的代码存在一些错误,我无法编译代码,但是我查看了存档中包含的PDF文件,并知道为什么您的TilingView很慢。
通常,在使用方法CGContextDrawPDFPage绘制CGContext中的PDF页面时,所有文本和矢量图形都会被渲染,PDF中的其他图形只会被绘制和缓存。因此,PDF文件有多大并不重要,但是如果您的PDF中有矢量图形,则会影响速度。看起来您的PDF中有一些矢量图形和数学方程式,这就是为什么它很慢的原因。我建议您尝试使用另一个不包含矢量图形的PDF文件,看看速度是否更快。
祝好!
Zheng

郑,感谢您的回复。在我的电脑上,使用最新的iOS 4.0.2 SDK可以构建和运行代码。至于PDF文件的内容,不幸的是,我不能选择用户决定尝试查看哪个PDF文件,我只能尽力处理任何有效的PDF文档。 - jbm

1

不要把猜测当作权威:PDF是大多数文档的基于向量的格式(不包括仅用作嵌入式TIFF图像容器的文档)。因此,当您像PhotoScroller一样平铺PDF时,实际上是要求手机为每个单独的瓷砖缩放和光栅化整个PDF(至少给定页面)。因此,与其像单个CATiledLayer一样只绘制一次,您需要为每个分辨率绘制多次。由于PDF本身是可缩放的格式,因此您应该能够为每个页面/比例尺度简单地渲染整个视图。

更新:我刚刚自己经历了这个过程,发现PhotoScroller示例存在一些逻辑问题,使其非常缓慢。基本上,它以1 / zoomScale的比例渲染每个瓷砖,然后将其缩小到zoomScale。因此,如果缩放为0.5,则以2倍渲染,然后将其缩小到0.5倍。非常缓慢且低效。


1
同意,CATiledLayer应该为您处理这个问题,对吧?如果能有一些诊断输出,甚至是从该类中提供委托API来让我们知道缓存的行为如何,根据我们设置的属性:瓷砖大小、细节、细节偏差,那就太好了。我想他们需要调整算法的空间。 - jbm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接