ios – 创建PDF时的内存警告和崩溃

ios – 创建PDF时的内存警告和崩溃,第1张

概述在生成大型PDF时,我的应用程序会在内存中收到警告,然后在PDF的生成过程中崩溃. PDF被绘制到Web视图中,当页面超过一定数量(取决于设备)时,我的内存不足 到目前为止,我对这个问题的研究使我理解我需要: 将UIGraphicsBeginPDFContextToData更改为IGraphicsBeginPDFContextToFile >创建临时文件的合理路径, >把它交给函数, >将文件提供 在生成大型pdf时,我的应用程序会在内存中收到警告,然后在pdf的生成过程中崩溃. pdf被绘制到Web视图中,当页面超过一定数量(取决于设备)时,我的内存不足

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

将UIGraphicsBeginPdfcontextToData更改为IGraphicsBeginPdfcontextTofile

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

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

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

@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 pagesint 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];  } }}

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

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

您想要的序列似乎是:

// 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 bothUIGraphicsEndPdfcontext();

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

好.我查看了你的代码,看起来你最终在内存中至少有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时的内存警告和崩溃所遇到的程序开发问题。

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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1074419.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存