【问题标题】:PDF memory warning/crashPDF 内存警告/崩溃
【发布时间】:2013-04-27 18:05:44
【问题描述】:

尽管对 Google、So 和 http://developer.apple.com/library/ios/#documentation/2ddrawing/conceptual/drawingprintingios/GeneratingPDF/GeneratingPDF.html 进行了研究。我仍然无法用我的应用程序找到这个问题的答案。加载视图后,我的应用程序会立即生成一个绘制到 Web 视图中的 PDF。问题是在收到内存警告和崩溃之前,我只能在 iPhone 4s 上生成大约 8 页,在 iPhone 5 上生成 14 页。

ICPDFEICRInspection1 2,3,4 等是大视图/xib 被绘制到 web 视图中

此时应用生成所有页面,然后将整个文档显示在webView中。

我的问题:我该如何改变这一点,以便我在用户滚动时一次只绘制一页,而不是先将其全部加载到内存中,循环遍历内容,将其绘制一页一次

 - (void)viewWillAppear:(BOOL)animated
{
LogCmd();

 [super viewWillAppear:animated];
 if (self.pdfData != nil && self.viewHasUnloaded == YES) {
    self.viewHasUnloaded = NO;
    [self.webView loadData:self.pdfData MIMEType:@"application/pdf" textEncodingName:@"utf-8" baseURL:nil];
    }
   }



- (void)viewDidAppear:(BOOL)animated
  {

  LogCmd();
  [super viewDidAppear:animated];
  if (self.pdfData == nil) {



    // Generate PDF
     [ICUtils showProgressViewWithTitle:@"Generating PDF. This may take a minute..."];
     [self performSelectorInBackground:@selector(generatePdf) withObject:nil];
  }
 }

  - (void)generatePdf
   {
   NSMutableArray *pagesArray = [NSMutableArray array];

  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;

}

【问题讨论】:

    标签: ios objective-c cocoa-touch memory-management pdf-generation


    【解决方案1】:

    一些可能的方法:

    1. UITableView。每个单元格包含一个页面。 iOS 要求您按需创建单元格和页面,并且只保留足够填满屏幕的内容。问题是 PDF 页面的呈现需要大量时间,这会导致滚动不顺畅。

    2. UICollectionView。相同但允许更大的灵活性,例如从左到右的页面。

    3. CATiledLayer。像谷歌地图一样,您可以通过在后台渲染来平滑滚动。我发现更复杂,实际上在显示文档方面并没有那么好。

    4. 创建一个 PDF 文件供 webView 呈现,而不是将所有页面呈现到内存中。系统会处理内存,它会平滑滚动而不会出现伪像。如果 PDF 页面不变,这可能是您最好的选择。

    【讨论】:

    • web 视图当前正在渲染它
    • 是的,但为了做好准备,他将 PDF 渲染到内存而不是文件。
    • 好吧,我的错,写文件有什么建议吗?
    • 看看你在哪里使用UIGraphicsBeginPDFContextToData?还有一个UIGraphicsBeginPDFContextToFile。给它一个文件路径而不是一个 NSData,你应该在路上了。
    • 这个我还没有更进一步,我真的不明白。我已更改为UIGraphicsBeginPDFContextToFile & ` NSURL *filepath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html" inDirectory:@"html"];` 但出现不兼容的指针类型错误,错误的访问错误 urrrrgh !
    【解决方案2】:

    您将所有 PDF 数据生成到内存数据结构中,这是一个坏主意。先尝试使用UIGraphicsBeginPDFContextToFile 将PDF 数据写入文件。完成后,将其加载到 Web 视图中。

    【讨论】:

    • 谢谢迈克,我不知道该怎么做,非常感谢任何建议/详细说明
    猜你喜欢
    • 2011-10-15
    • 1970-01-01
    • 2013-08-02
    • 1970-01-01
    • 2011-09-12
    • 2015-08-08
    • 2014-04-19
    • 2015-08-16
    • 1970-01-01
    相关资源
    最近更新 更多