为什么这个 CATiledLayer/PDF 代码很慢?
这是代码:
https://www.dropbox.com/s/o42wy36x4qhrbpt/PDFScroller .zip
我采用了 WWDC 2010 PhotoScroller
示例代码,该代码实现了用于缩放的嵌套 UIScrollViews
,在用于分页的 UIScrollView
内,并进行了交换我认为显示多页 PDF 而不是图像所需的代码量最少。
有用。但在我的 iPhone4 上速度很慢,绘制第一页大约需要三秒,在我的 iPod Touch 上甚至更慢。我可以看着它绘制各个瓷砖。在我的另一个 CATiledLayer
实现中,该 PDF 已经打开得更快,没有可见的图块绘图,该实现仅使用单个 CATiledLayer
/UIScrollView
和触摸事件来更改页面。我想使用这个 PhotoScroller
技术,它非常好。
我用 Instruments 中的 CPU Sampler 观看了它,它似乎不是 PDF 渲染代码,看起来时间被占用在线程和消息传递上。如果有人能帮助指出这个示例是如何产生开销的,我将不胜感激。
谢谢,
Jim
更新 1:我最初使用定义示例代码中的 TilingView
类技术
+ (Class) layerClass {
return [CATiledLayer class];
}
,然后在 - (void)drawRect:(CGRect)rect
中绘制,但切换了到显式的 CATiledLayer 子类作为第一次尝试,看看它是否会产生影响,但它没有,所以我将代码按原样保留在此处发布。 TilingView 中还缺少 [tiledLayer release];
泄漏。
Here is the code:
https://www.dropbox.com/s/o42wy36x4qhrbpt/PDFScroller.zip
I took the WWDC 2010 PhotoScroller
sample code that implements nested UIScrollViews
for zooming, inside a UIScrollView
for paging, and swapped out what I thought would be minimal amount of code required for displaying a multi-page PDF instead of images.
It works. But it's slow on my iPhone4, about three seconds to paint the first page, and even slower on my iPod Touch. I can watch it painting the individual tiles. This same PDF already opens up more quickly, with no visible tile drawing, in an alternate CATiledLayer
implementation I have which simply uses a single CATiledLayer
/UIScrollView
and touch events to change pages. I'd like to use this PhotoScroller
technique, it's very nice.
I watched it with CPU Sampler in Instruments, and it doesn't seem to be the PDF rendering code, it looks like the time is taken up in threading and messaging. I'd appreciate it if someone could help point out what this sample is doing to incur the overhead.
Thanks,
Jim
Update 1: I had originally used the TilingView
class technique from the sample code of defining
+ (Class) layerClass {
return [CATiledLayer class];
}
And then drawing in - (void)drawRect:(CGRect)rect
but switched to the explicit CATiledLayer
subclass as a first attempt at seeing whether it would make a difference, but it did not, and so I left the code as-is for posting here. There is also a missing [tiledLayer release];
leak in TilingView.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
请参阅此主题 适用于 iPhone / iPad 的快速且精简的 PDF 查看器/iOs - 技巧和提示? 用于 PDF 渲染技巧。
See this Thread Fast and Lean PDF Viewer for iPhone / iPad / iOs - tips and hints? for PDF rendering tips.
由于您的代码包含几个错误,我无法编译代码,但我查看了存档中包含的 PDF 文件,我知道您的 TilingView 速度慢的原因。
通常,当您使用方法
CGContextDrawPDFPage
: 在CGContext
中绘制 pdf 页面时,所有文本和矢量图形都会被渲染,而其他内容(例如 PDF 中的普通图形)只会被绘制并缓存。因此,PDF 文件有多大并不重要,但 PDF 中是否有矢量图形才重要。看来你的PDF中有一些矢量图形和一些数学方程,这就是它慢的原因。我建议您尝试使用另一个不包含矢量图形的 PDF 文件,看看它是否更快。干杯
郑
as your code contains couple of errors and i can not compile the code, but i took a look at the PDF file which was included in the archive and i know the reason why your TilingView is slow.
Normally when you draw a pdf page in a
CGContext
using the methodCGContextDrawPDFPage
:, all text and vectorial graphics were rendered and other things like normal graphics in the PDF are just get drawn and cached. So it does not matter how big the PDF file is, but it does matter if you have vectorial grahics in your PDF. It seems that you have some vectorial graphic in your PDF and also some math equations, that's the reason why it is slow. I suggest you to try with another PDF file which does not contain vectorial graphics and see if it is faster.Cheers
Zheng
请勿以任何权威推测:PDF是大多数文档的基于矢量的格式(不包括那些仅用作嵌入 TIFF 图像容器的文档)。因此,当您像 PhotoScroller 一样平铺 PDF 时,您实际上是要求手机对每个单独平铺的整个 PDF(至少是给定页面)进行缩放和光栅化。因此,您不必像为单个 CATiledLayer 那样绘制一次,而是为每个分辨率执行多次。由于 PDF 本身是一种可缩放格式,因此您应该能够简单地为每个页面/比例渲染一次整个视图。
更新:我自己刚刚经历过这个过程,PhotoScroller 示例存在一些逻辑问题,导致速度非常慢。基本上,它以 1/zoomScale 渲染每个图块,然后缩放回 ZoomScale。因此,如果缩放为 0.5,它会以 2x 渲染,然后将其缩小到 0.5x。非常慢而且效率低下。
Conjecture not to be taken with any sort of authority: PDF is a vector based format for most documents (excluding those that simply serve as a container for embedded TIFF images). So when you tile the PDF like the PhotoScroller, you essentially ask the phone to scale and rasterize the whole PDF (well at least the given page) for each individual tile. So rather than painting it once as you might for a single CATiledLayer, you do it multiple times for each resolution. Since the PDF is a scalable format in itself, you should be able to simply render the entire view once for each page/scale.
Update: Having just gone through this myself, the PhotoScroller sample has some logic issues that make it very slow. Basically it renders the each tile at 1/zoomScale then scales is back down to zoomScale. So if zoom is at .5 it renders at 2x then scales that back down to 0.5x. Very slow an inefficient.