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

Ipad 高分辨率pdf在页面之间导航时导致崩溃,ipad,pdf,ios5,quartz-2d,Ipad,Pdf,Ios5,Quartz 2d,我正在实现一个pdf阅读器。我编写代码的方式足以满足许多pdf的需要。突然,一个单一的pdf以300MB(总共1000页)的速度出现在图片中。pdf在长达70页的时间内工作正常。它正在扼杀我的应用程序。我正在检查分区(IPad1,V5.0)和模拟器(V5.0).在模拟器中,我可以在从1开始到最后一页的所有页面上导航,但在设备上我不能这样做。我在仪器工具中看到了内存分配 在显示内存分配和内存利用率波动的图像矩形框中,对于每个新呈现的页面(首次打开应用程序后)CGContextDrawPDFPage

我正在实现一个pdf阅读器。我编写代码的方式足以满足许多pdf的需要。突然,一个单一的pdf以300MB(总共1000页)的速度出现在图片中。pdf在长达70页的时间内工作正常。它正在扼杀我的应用程序。我正在检查分区(IPad1,V5.0)和模拟器(V5.0).在模拟器中,我可以在从1开始到最后一页的所有页面上导航,但在设备上我不能这样做。我在仪器工具中看到了内存分配

在显示内存分配和内存利用率波动的图像矩形框中,对于每个新呈现的页面(首次打开应用程序后)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);
otherPageRef=CGPDFDocumentGetPage(myDocumentRef,c);
cropBox=CGPDFPageGetBoxRect(otherPageRef,kCGPDFCropBox);
CGContextSaveGState(ctx);
CGContextSetRGBFillColor(ctx,1.0,1.0,1.0,1.0);
CGContextFillRect(ctx,cgcontextgetclipboondingbox(ctx));
CGFloat aspectRatio=aspectFitSize.width/aspectFitSize.height;
CGRect targetRect=layer.bounds;
CGFloat xScale=targetect.size.width/cropBox.size.width;
CGYScale=(targetect.size.height-\uuu TOP\u BRANDING\u BAR\u height)/cropBox.size.height;
CGFloat scaleToApply=(xScale

有人能猜出我的应用程序崩溃的原因吗?请建议我使用处理技术。我甚至尝试了我的cgpdfdocumentRef释放和保留方法,但没有用。你的建议对我更有用。提前谢谢。

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

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

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

  • 打开PDF
  • 画1-5页
  • 关闭PDF
  • 如有需要,重复上述步骤
  • 我使用了这种方法,即使是有很多图像(杂志)的大PDF,它也能很好地工作


    有关更多信息,您可能需要查看讨论。

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

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

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

  • 打开PDF
  • 画1-5页
  • 关闭PDF
  • 如有需要,重复上述步骤
  • 我使用了这种方法,即使是有很多图像(杂志)的大PDF,它也能很好地工作


    有关更多信息,您可能希望查看讨论。

    +1感谢您的精彩提示,我也遵循您的提示,让我检查它是如何工作的。在执行上述步骤后,我的仪器内存波动到25MB会导致任何崩溃问题。我没有确切的数字,“这取决于”,但我认为在你的应用程序中使用30-50MB是安全的。顺便说一句,您可以在代码中处理内存警告(我在我的代码中已经这样做了)。每当操作系统发出内存警告时,只需关闭并重新打开PDF。我尝试使用下面的代码刷新文档,但几乎不需要时间更新任何猜测,以缩短pdfPagesRendered=0的时间;NSLog(@“before=%@,[NSDate日期]);NSAutoreleasePool*池=[[NSAutoreleasePool alloc]init];isMemoryWaringOccured=是;CGPDFDocumentRelease(myDocumentRef);pdfUrl=[[NSURL alloc]initFileURLWithPath:[self.kbDataSource pdfPath]];myDocumentRef=CGPDFDocumentCreateWithURL(pdfUrl);[pdfUrl释放];[池释放];NSLog(@“之后=%@,[NSDate日期]);我不知道您为什么在此代码中使用
    NSAutoreleasePool
    。可能不需要。除此之外,我不知道如何使PDF的打开速度更快