iOS   发布时间:2022-03-30  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了ios – 创建PDF时的内存警告和崩溃大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
生成大型PDF时,我的应用程序会在内存中收到警告,然后在PDF的生成过程中崩溃. PDF被绘制到Web视图中,当页面超过一定数量(取决于设备)时,我的内存不足

到目前为止,我对这个问题的研究使我理解我需要:

将uIGraphicsBeginPDFContextToData更改为IGraphicsBeginPDFContextToFile

>创建临时文件的合理路径,
>把它交给函数,
>将文件提供给webview加载.
>完成后删除文件.

问题是,然我认为我(仅仅)在市政中抓住它,但我不知道如何实现这一点,或者完全理解它以便在我的代码中实现它.这个问题的建议非常适合

我也对任何其他想法开放以阻止内存崩溃

@H_301_24@@interface ICPDFPreviewController () @property (nonatomic,strong) Certificate *certificate; @property (nonatomic,strong) NSData *pdfData; @property (nonatomiC) BOOL viewHasUnloaded; - (void)generatePdf; - (void)pdfDone:(NSData *)data; - (NSData *)createPdfWithPages:(NSArray *)pages; @end @implementation ICPDFPreviewController @synthesize certificate=_certificate; @synthesize scrollView=_scrollView; @synthesize webView=_webView; @synthesize pdfData=_pdfData; @synthesize viewHasUnloaded=_viewHasUnloaded; - (void)generatePdf { NSMutableArray *pagesArray = [NSMutableArray array]; if ([self.certificate.certificateType.title isEqualToString:@"Minor Works"]) { [pagesArray addObject:[[ICPDFMinorWorksPage1 alloc] initWithCertificate:self.certificate]]; [pagesArray addObject:[[ICPDFMinorWorksPage2 alloc] initWithCertificate:self.certificate]]; } else if ([self.certificate.certificateType.title isEqualToString:@"EIC"]) { [pagesArray addObject:[[ICPDFEICPage1 alloc] initWithCertificate:self.certificate]]; [pagesArray addObject:[[ICPDFEICPage2 alloc] initWithCertificate:self.certificate]]; [pagesArray addObject:[[ICPDFEICPage3 alloc] initWithCertificate:self.certificate]]; [pagesArray addObject:[[ICPDFEICPage4 alloc] initWithCertificate:self.certificate]]; [pagesArray addObject:[[ICPDFEICPage5 alloc] initWithCertificate:self.certificate]]; [self addDiStributionBoardsToPagesArray:pagesArray]; ICPDFEICPageFinal *pageFinal = [[ICPDFEICPageFinal alloc] initWithCertificate:self.certificate]; pageFinal.pagenumber.text = [NSString StringWithFormat:@"%d",pagesArray.count+1]; [pagesArray addObject:pageFinal]; } else if ([self.certificate.certificateType.title isEqualToString:@"Domestic EIC"]) { [pagesArray addObject:[[ICPDFDomesticEICPage1 alloc] initWithCertificate:self.certificate]]; [pagesArray addObject:[[ICPDFDomesticEICPage2 alloc] initWithCertificate:self.certificate]]; [pagesArray addObject:[[ICPDFDomesticEICPage3 alloc] initWithCertificate:self.certificate]]; [pagesArray addObject:[[ICPDFDomesticEICPage4 alloc] initWithCertificate:self.certificate]]; [self addDiStributionBoardsToPagesArray:pagesArray]; [pagesArray addObject:[[ICPDFDomesticEICPageFinal alloc] initWithCertificate:self.certificate]]; } else if ([self.certificate.certificateType.title isEqualToString:@"EICR"]) { [pagesArray addObject:[[ICPDFEICRPage1 alloc] initWithCertificate:self.certificate]]; [pagesArray addObject:[[ICPDFEICRPage2 alloc] initWithCertificate:self.certificate]]; [self addObservationsToPagesArray:pagesArray]; [self addDiStributionBoardsToPagesArray:pagesArray]; [pagesArray addObject:[[ICPDFEICRinspection alloc] initWithCertificate:self.certificate]]; [pagesArray addObject:[[ICPDFEICRinspectionPage1 alloc] initWithCertificate:self.certificate]]; [pagesArray addObject:[[ICPDFEICRinspectionPage2 alloc] initWithCertificate:self.certificate]]; [pagesArray addObject:[[ICPDFEICRinspectionPage3 alloc] initWithCertificate:self.certificate]]; [pagesArray addObject:[[ICPDFEICRPageFinal alloc] initWithCertificate:self.certificate]]; } // Set page count on all pages int pagenumber = 0; for (ICCertificateComponent *page in pagesArray) { page.pagenumber.text = [NSString StringWithFormat:@"%d",++pagenumber]; page.PageCount.text = [NSString StringWithFormat:@"%d",pagesArray.count]; } NSData *pdfData = [self createPdfWithPages:pagesArray]; [self performSELEctorOnMainThread:@SELEctor(pdfDone:) withObject:pdfData waitUntilDone:YES]; } - (void)pdfDone:(NSData *)data { self.pdfData = data; [self.webView loadData:self.pdfData MIMEType:@"application/pdf" textEncodingName:@"utf-8" baseURL:nil]; [ICUtils removeProgressview]; } - (NSData *)createPdfWithPages:(NSArray *)pages { // Creates a mutable data object for updating with binary data,like a byte array NSMutableData *pdfData = [NSMutableData data]; ICCertificateComponent *firstPage = [pages objectATindex:0]; UIGraphicsBeginPDFContextToData(pdfData,firstPage.contentView.bounds,nil); for (int i = 0; i < pages.count; i++) { ICCertificateComponent *thisPage = [pages objectATindex:i]; UIGraphicsBeginPDFPageWithInfo(thisPage.contentView.bounds,nil); CGContextRef pdfContext = UIGraphicsGetCurrentContext(); [thisPage.contentView.layer renderInContext:pdfContext]; } UIGraphicsEndPDFContext(); return pdfData; } - (void)addDiStributionBoardsToPagesArray:(NSMutableArray *)pagesArray { int PageCount = pagesArray.count; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"createdAt" ascending:YES]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor,nil]; NSArray *boards = [self.certificate.diStributionBoards sortedArrayUsingDescriptors:sortDescriptors]; for (DiStributionBoard *thisBoard in boards) { DebugLog(@"CreaTing a board page"); ICPDFDiStributionBoard *boardPage = [[ICPDFDiStributionBoard alloc] initWithDiStributionBoard:thisBoard]; boardPage.pagenumber.text = [NSString StringWithFormat:@"%d",++PageCount]; DebugLog(@"Page number is %d",PageCount); [pagesArray addObject:boardPage]; NSSortDescriptor *circuitDescriptor = [[NSSortDescriptor alloc] initWithKey:@"createdAt" ascending:YES]; NSArray *circuitDescriptors = [[NSArray alloc] initWithObjects:circuitDescriptor,nil]; NSArray *circuits = [thisBoard.circuits sortedArrayUsingDescriptors:circuitDescriptors]; //int circuitCount = circuits.count; ICPDFCircuitDetails *circuitDetails = boardPage.circuitDetails; int circuitCount = 0; for (Circuit *thisCircuit in circuits) { circuitCount++; if (circuitCount > 16) { // Add an extension page DebugLog(@"Adding an extension sheet"); circuitCount = 1; ICPDFDiStributionBoardExtension *boardExtension = [[ICPDFDiStributionBoardExtension alloc] initWithDiStributionBoard:thisBoard]; [pagesArray addObject:boardExtension]; boardExtension.pagenumber.text = [NSString StringWithFormat:@"%d",++PageCount]; circuitDetails = boardExtension.circuitDetails; } NSString *key = [NSString StringWithFormat:@"circuitRow%d",circuitCount]; ICCircuitRow *circuitRow = [circuitDetails valueForKey:key]; [circuitRow populateFromCircuit:thisCircuit]; } } }

调试控制台警告是这些的负载,然后崩溃

@H_301_24@2013-02-08 10:38:35.475 iCertifi[5772:907] Received memory warning. 2013-02-08 10:38:35.477 iCertifi[5772:907] <ICPDFPreviewController: 0x1eb28930> didReceiveMemoryWarning

解决方法

很久以前,在一个完全不同的平台上,我正在生成PDF文件并遇到这种问题.解决方案是一次生成一个页面(关闭每个页面(不是文档),然后打开下一个页面进行成像).这对我的许多页面文档产生了巨大的影响.查看您的代码,这与您在此处遇到的问题相同.实际上,您还有一个问题,就是首先以图形方式在内存中构建所有页面数据,然后在内存中构建所有pdf页面并使其崩溃.请阅读以下有关如何解决问题的详细信息.

here

您想要的序列似乎是:

@H_301_24@// start pdf document using default page size (CGRectZero) UIGraphicsBeginPDFContextToFile(pdfFilename,CGRectZero,nil); // then loop through your content drawing it one page at a time. for ( page p in pages ) // or whatever you are cycling over for page content { UIGraphicsBeginPDFPage(); // or UIGraphicsBeginPDFPageWithInfo // do your drawing to the page here by drawing to the current graphics context. // if you are setTing up transforms and such } // close out the last page and the document both UIGraphicsEndPDFContext();

所以这应该做的是一次将内存中的渲染数据量保持为一页(加上文档全局数据的一些开销).

好.我查看了你的代码,看起来你最终在内存中至少有2个渲染页面的副本,如果我正确理解它.

这是关键 – 一次只能绘制一页.你没有显示所有ICPDFEICRPage1等等,但看起来它们是将页面内容呈现给某种UIView的对象?这意味着他们拥有整个视图的像素数据(即副本1).因此,您甚至在渲染任何pdf页面之前,将为每个页面使用内存.然后打开pDF页面上下文,将其呈现为NSMutableData(这是数据的第二个副本).

一个问题是:为什么要渲染某种内存构造(视图),而不是在打印该页面时只渲染到每个页面的pdf页面图形上下文?我猜这是因为你有一个UIView层次结构,其字段和一切都在xib文件中定义,这样你就不必手动完成所有的字符串布局和绘图.正确?

如果是这样,那么要做的就是让你的pages数组成为一个数组,列出你想要的ICPDFEICR …对象的哪种顺序,而不是实际分配的对象本身.也许为每种可能类型的页面,观察,分发板等定义枚举.然后你的pages数组只是一个整数数组(那些枚举按你想要在文档中显示的顺序).

然后,仅为当前页面分配实际对象,将其映像到页面,然后在执行下一页之前将其释放.

另外,我假设(希望!)你正在使用ARC,否则你在这代码中会有很多内存泄漏(!!!).

希望这足以让你开始走上正轨.哦,使用文件技术,你需要给它一个文件路径,然后你只需将该路径作为file:// url传递给webview进行显示.

然现在我想到了,为什么你使用UIWebView来显示PDF?请查看Zooming PDF Viewer示例,以获取不会尝试将整个PDF文档加载到内存中以显示它的替代方法.

大佬总结

以上是大佬教程为你收集整理的ios – 创建PDF时的内存警告和崩溃全部内容,希望文章能够帮你解决ios – 创建PDF时的内存警告和崩溃所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。