高分辨率 pdf 在页面之间导航时导致崩溃

发布于 2025-01-03 22:08:24 字数 2512 浏览 0 评论 0原文

我正在实现一个 pdf 阅读器。我编写代码的方式足以满足许多 pdf 的需求,突然一个 pdf 大小为 300MB(总共 1000 页)。该 pdf 工作正常,最多 70 页,之后它正在杀死我的应用程序检查设备(IPad1,V5.0)和模拟器(V 5.0)。在模拟器中,我可以导航从第 1 页开始到最后一页的所有页面,但进入设备时我无法做到这一点我在“仪器工具” Image 中看到了内存分配

在图像矩形框中显示我的内存分配和内存利用率的波动,对于新渲染的每个单页(打开应用程序后第一次)CGContextDrawPDFPage方法增加了2MB内存。我不知道为什么CGContextDrawPDFPage急剧增加。我看到很多关于此的博客,但没有用,浪费时间。下面是我的示例代码,

otherPageRef = CGPDFDocumentGetPage(myDocumentRef, c);

            cropBox = CGPDFPageGetBoxRect(otherPageRef, kCGPDFCropBox);
            CGContextSaveGState(ctx);
            CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0);
            CGContextFillRect(ctx,CGContextGetClipBoundingBox(ctx));
            CGFloat aspectRatio=aspectFitSize.width/aspectFitSize.height;
            CGRect targetRect = layer.bounds;
            CGFloat xScale = targetRect.size.width / cropBox.size.width;
            CGFloat yScale = (targetRect.size.height-__TOP_BRANDING_BAR_HEIGHT) / cropBox.size.height;
            CGFloat scaleToApply = (xScale < yScale) ? xScale : yScale;
            CGContextTranslateCTM(ctx, -cropBox.origin.x, layer.bounds.size.height- __TOP_BRANDING_BAR_HEIGHT +cropBox.origin.y);
            CGContextScaleCTM(ctx, 1.0, -1.0);
            CGContextConcatCTM(ctx, CGAffineTransformMakeScale(scaleToApply, scaleToApply));
            if (scaleToApply == yScale){
                CGContextConcatCTM(ctx, CGAffineTransformMakeTranslation((layer.bounds.size.width-(cropBox.size.width*scaleToApply)-cropBox.origin.x)/(scaleToApply * 2.0), 0));
            }
            else{
                if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){
                    CGContextConcatCTM(ctx, CGAffineTransformMakeTranslation(0, (layer.bounds.size.height- __TOP_BRANDING_BAR_HEIGHT -(cropBox.size.height*scaleToApply))/(scaleToApply*2.0)));
                }
                else {
                    CGContextConcatCTM(ctx, CGAffineTransformMakeTranslation(0, (layer.bounds.size.height- __TOP_BRANDING_BAR_HEIGHT -(cropBox.size.height*scaleToApply))/(scaleToApply*2.0)));
                }
            }


            CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh); 
            CGContextSetRenderingIntent(ctx, kCGRenderingIntentDefault);
            CGContextDrawPDFPage(ctx, otherPageRef);
            CGContextRestoreGState(ctx);

任何人都可以猜测我的应用程序崩溃的原因是什么,请建议我处理技术。我什至尝试了我的 cgpdfdocumentRef 释放和保留方法,但没有用.您的建议对我更有用。提前致谢。

I am implementing a pdf reader.The way i am writing code is sufficient for many pdf's suddenly one single pdf came into picture with 300MB(total 1000 pages).The pdf is working fine up to 70 pages later it is killing my application i am checking in the divice(IPad1,V5.0) and simulator(V 5.0).In simulator i can navigate with all pages from starts at 1 till the last page but coming to device i cant do that.I seen memory allocation in the "Instruments tool" Image

On the image rectangle box showing me memory allocation and fluctuating of the memory utilization,for each single page newly rendered(first time after opening the app) CGContextDrawPDFPage method increasing 2MB of memory.I dont know why CGContextDrawPDFPage increasing drastically.I seen many blogs on this but there is no use and waste of time.Below is my sample code

otherPageRef = CGPDFDocumentGetPage(myDocumentRef, c);

            cropBox = CGPDFPageGetBoxRect(otherPageRef, kCGPDFCropBox);
            CGContextSaveGState(ctx);
            CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0);
            CGContextFillRect(ctx,CGContextGetClipBoundingBox(ctx));
            CGFloat aspectRatio=aspectFitSize.width/aspectFitSize.height;
            CGRect targetRect = layer.bounds;
            CGFloat xScale = targetRect.size.width / cropBox.size.width;
            CGFloat yScale = (targetRect.size.height-__TOP_BRANDING_BAR_HEIGHT) / cropBox.size.height;
            CGFloat scaleToApply = (xScale < yScale) ? xScale : yScale;
            CGContextTranslateCTM(ctx, -cropBox.origin.x, layer.bounds.size.height- __TOP_BRANDING_BAR_HEIGHT +cropBox.origin.y);
            CGContextScaleCTM(ctx, 1.0, -1.0);
            CGContextConcatCTM(ctx, CGAffineTransformMakeScale(scaleToApply, scaleToApply));
            if (scaleToApply == yScale){
                CGContextConcatCTM(ctx, CGAffineTransformMakeTranslation((layer.bounds.size.width-(cropBox.size.width*scaleToApply)-cropBox.origin.x)/(scaleToApply * 2.0), 0));
            }
            else{
                if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){
                    CGContextConcatCTM(ctx, CGAffineTransformMakeTranslation(0, (layer.bounds.size.height- __TOP_BRANDING_BAR_HEIGHT -(cropBox.size.height*scaleToApply))/(scaleToApply*2.0)));
                }
                else {
                    CGContextConcatCTM(ctx, CGAffineTransformMakeTranslation(0, (layer.bounds.size.height- __TOP_BRANDING_BAR_HEIGHT -(cropBox.size.height*scaleToApply))/(scaleToApply*2.0)));
                }
            }


            CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh); 
            CGContextSetRenderingIntent(ctx, kCGRenderingIntentDefault);
            CGContextDrawPDFPage(ctx, otherPageRef);
            CGContextRestoreGState(ctx);

can any one guess what is the cause for my app crashing and please suggest me to handling technique.I even tried my cgpdfdocumentRef releasing and retaining method but no use.Your suggestion is more useful for me.Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

终弃我 2025-01-10 22:08:25

基本上,您的应用程序使用了太多内存并被操作系统杀死。模拟器有足够的内存,但 iPad 没有。这就是设备和模拟器之间存在行为差异的原因。

使用大量内存的原因是 Quartz 2D 的一个错误/功能。当绘制页面时,该页面使用的所有对象都会被读入内存并被解压缩。这些解压后的对象由 Quartz 2D 缓存(明智的决定)。问题是:在 PDF 关闭之前,这些对象不会从缓存中删除。

因此,显而易见的方法是:

  1. 打开 PDF
  2. 绘制 1-5 页
  3. 关闭 PDF
  4. 如果需要则重复

我使用了这种方法,即使对于包含大量图像(杂志)的大型 PDF,它也能正常工作。

有关更多信息,您可能需要查看 适用于 iPhone / iPad / iO 的快速、精益 PDF 查看器 - 提示和提示? 讨论。

Basically, your app uses too much memory and gets killed by the OS. Simulator has plenty of memory but iPad doesn't. This is why there is a difference in behavior between device and simulator.

The reason of large amount of memory being used is a bug/feature of the Quartz 2D. When a page is drawn, all objects used by the page are read into memory and are decompressed. And these decompressed objects are cached (wise decision) by the Quartz 2D. The problem is: these objects won't be removed from the cache until the PDF is closed.

So, the obvious way to go is:

  1. Open a PDF
  2. Draw 1-5 pages
  3. Close the PDF
  4. Repeat if needed

I used this approach and it works fine even for big PDFs with lots of images (magazines).

For more information you might want to have a look at Fast and Lean PDF Viewer for iPhone / iPad / iOs - tips and hints? discussion.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文