Quartz PDF API导致内存崩溃

时间:2010-06-21 20:42:59

标签: iphone pdf ipad quartz-graphics quartz-2d

我使用Quartz PDF API for iOS遇到了崩溃问题。目前我正在使用SDK 4.0 GM Seed进行编译并在我的3.2 iPad上运行(我尝试使用3.2 SDK,结果相同)。

我使用的所有代码都基于标准Apple Quartz文档以及互联网的各种来源。所以我无法想象我正在做一些完全不同或错误的事情。

代码在模拟器(所有版本,它是一个通用应用程序)中运行完美,甚至在使用“模拟内存警告”功能时也是如此。我使用了泄漏工具,它没有发现任何泄漏。构建和分析也找不到任何东西。我的库中没有留下崩溃或内存不足的日志。

所有这些让我相信设备内存不足。这通过说50个pdf页面后发生,大约35%有一些图像(一些完整页面的某些图标)。它不会在任何特定页面上崩溃。我加载的pdf大约是75页和3.5MB。

我在本网站和互联网上仔细阅读了类似的问题,并在下面的代码中应用了一些建议。我现在在每个页面转向发布pdf文档引用,我不再保留/发布页面引用。我还简化了从使用CGImages到仅使用UIGraphicsGetImageFromCurrentImageContext函数的图像交换。我已经尝试了各种用于切换图像的实现,包括使用新分配的临时实例(使用[[UIImageView alloc] iniWithImage:UIGraphicsGetImageFromCurrentImageContext()])完全替换pdfImgView,使用pdfImgView的setter并释放temp。所有变体都通过Leaks和Analyzer测试,但仍然表现出相同的崩溃行为。

所以,在我完全放弃PDF之前,有什么我应该尝试或者我缺少的东西吗?

查看在界面处理程序中调用的控制器代码,以交换页面和首次加载:

[self drawPage];

// ...animation code...simple CATransition animation...crashes with or without

// scrollView is a UIScrollView that is a subview of self.view
[scrollView.layer addAnimation:transition forKey:nil];
// pdfImgView is a UIImageView that is a subview of scrollView
pdfImgView.image = UIGraphicsGetImageFromCurrentImageContext();

drawPage方法用于配置和绘制PDF页面到上下文:

[CFURLRef pdfURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("BME_interior.pdf"), NULL, NULL);
pdfRef = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL); // instance variable, not a property
CFRelease(pdfURL);
CGPDFPageRef page = CGPDFDocumentGetPage(pdfRef, currentPage);

CGRect box = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
// ...setting scale and imageHeight, both floats...

if (UIGraphicsBeginImageContextWithOptions != NULL) {
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.view.frame.size.width, imageHeight), NO, 0.0);
} else {
    UIGraphicsBeginImageContext(CGSizeMake(self.view.frame.size.width, imageHeight));
}
CGContextRef context = UIGraphicsGetCurrentContext();
NSLog(@"page is %d, context is %d, pdf doc is %d, pdf page is %d", currentPage, context, pdfRef, page); // all prints properly

// ...setting up scrollView for new page, using same instance...

CGContextTranslateCTM(context, (self.view.frame.size.width-(box.size.width*scale))/2.0f, imageHeight);
CGContextScaleCTM(context, scale, -1.0*scale);

CGContextSaveGState(context);
CGContextDrawPDFPage(context, page);
CGContextRestoreGState(context);

CGPDFDocumentRelease(pdfRef);
pdfRef = NULL;

2 个答案:

答案 0 :(得分:1)

啊哈!我在开始新的图像上下文之前添加UIGraphicsEndImageContext();来修复崩溃。我现在甚至都没有得到记忆警告......

答案 1 :(得分:0)

致电

CGContextSetInterpolationQuality(context, kCGInterpolationHigh); 
CGContextSetRenderingIntent(context, kCGRenderingIntentDefault);

之前CGContextDrawPDFPage解决了我的类似问题。

致于约翰恩的回答: CGContextDrawPDFPage taking up large amounts of memory