我在使用适用于 iOS 的 Quartz PDF API 时遇到崩溃问题。目前我正在使用 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 的设置器并释放临时。所有变体都通过了泄漏和分析器测试,但仍然表现出相同的崩溃行为。
那么,在我完全放弃 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();
用于配置 PDF 页面并将其绘制到上下文的 drawPage 方法:
[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;