2013-11-14 42 views
2

我的应用程序接受了UIWebView的内容并生成了网页的PDF。这在较小的页面上工作正常,但当它达到约10页时,它会崩溃“由于内存压力”。另外,这是一个ARC应用程序。生成PDF时的内存压力崩溃

的主要答案,我所看到的是使用的UIGraphicsBeginPDFContextToData并改变使用File我仍然获得了内存压力崩溃后UIGraphicsBeginPDFContextToFile代替。我不明白为什么它不从内存中清除页面。我还在循环中添加了@autoreleasepool { ... },正如另一个问题中所建议的那样。关于我在这里做错的任何想法?

这里的PDF创建代码:

UIGraphicsBeginPDFContextToFile(dataFile, CGRectZero, nil); 

for (int i = 0; i < pages; i++) { 
    @autoreleasepool { 
     NSLog(@"Creating Page %i", i); 
     // Check to see if page draws more than the height of the UIWebView 
     if ((i+1) * 720 > height) { 
      CGRect f = [_appWebView frame]; 
      f.size.height -= (((i+1) * 720.0) - height); 
      [_appWebView setFrame: f]; 
     } 

     UIGraphicsBeginPDFPage(); 
     CGContextRef currentContext = UIGraphicsGetCurrentContext(); 
     CGContextTranslateCTM(currentContext, 36, 36); // Translate for 0.5" margins 
     [[[_appWebView subviews] lastObject] setContentOffset:CGPointMake(0, 720 * i) animated:NO]; 
     [_appWebView.layer renderInContext:currentContext]; 
    } 
} 
UIGraphicsEndPDFContext(); 

下面是完整的方法,如果它可以帮助任何:

-(void) generatePDF { 

    startingFrame = _appWebView.frame; 

    // Memory warning seems to happen on almost every PDF, clear cache here to be proactive. 
    [[NSURLCache sharedURLCache] removeAllCachedResponses]; 

    UIWebView *webView = [[UIWebView alloc] initWithFrame: CGRectMake(0, 0, 6.5 * 72, 9 * 72)]; 
    [webView setDelegate: self]; 

    // Adjust to letter size paper size in portrait mode 
    CGRect frame = _appWebView.frame; 
    frame.size.height = 10*72; // 11" - 1" Margins = 720px (72px/inch) 
    frame.size.width = 7.5*72; // 8.5 - 1" Margins = 612px (72px/inch) 
    _appWebView.frame = frame; 

    [_appWebView stringByEvaluatingJavaScriptFromString:@"window.scroll(0, 0);"]; 

    // Get the height of our webView 
    NSString *heightStr = [_appWebView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"]; 

    int height = [heightStr intValue]; 

    // Get the number of pages needed to print. 10 * 72 = 720 
    int pages = ceil(height/720.0); 

    // File 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *dataFile = [documentsDirectory stringByAppendingPathComponent:@"Configuration.pdf"]; 
    NSLog(@"File: %@", dataFile); 

    UIGraphicsBeginPDFContextToFile(dataFile, CGRectZero, nil); 

    for (int i = 0; i < pages; i++) { 
     @autoreleasepool { 
      NSLog(@"Creating Page %i", i); 
      // Check to see if page draws more than the height of the UIWebView 
      if ((i+1) * 720 > height) { 
       CGRect f = [_appWebView frame]; 
       f.size.height -= (((i+1) * 720.0) - height); 
       [_appWebView setFrame: f]; 
      } 

      UIGraphicsBeginPDFPage(); 
      CGContextRef currentContext = UIGraphicsGetCurrentContext(); 
      CGContextTranslateCTM(currentContext, 36, 36); // Translate for 0.5" margins 
      [[[_appWebView subviews] lastObject] setContentOffset:CGPointMake(0, 720 * i) animated:NO]; 
      [_appWebView.layer renderInContext:currentContext]; 
     } 
    } 

    UIGraphicsEndPDFContext(); 

    // Adjust to original size 
    _appWebView.frame = startingFrame; 
} 
+0

附加我的答案,你开始UIGraphicsBeginPDFPage();但你永远不会结束它。我对结构没有什么了解,但是对于Graphics环境,通常有一个开始和结束。 – Putz1103

+0

我发现没有'UIGraphicsEndPDFPage'方法来调用这个方法会结束页面。它在开始下一个页面时结束上一页。 – mpaq

回答

0

我不知道你所得到的内存错误的理由,但我在搜索PDF时遇到了类似的问题。基本上,操作系统将整个PDF加载到内存中,然后搜索,然后删除PDF,甚至认为我要一页接一页。我的解决方案是一次只做一页,并为我解决了内存问题。

我的代码如下所示:

NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init]; 
operationQueue.MaxConcurrentOperationCount = 1; 


for(int i = 1; i <= totalPages; i++) 
{ 

    // a block of operation 
    [operationQueue addOperationWithBlock:^{ 


    }]; 
} 
+0

此方法错误:':CGContextGetBaseCTM:无效的上下文0x0。这是一个严重的错误。此应用程序或其使用的库正在使用无效的上下文,从而导致系统稳定性和可靠性的整体降级。这个通知是礼貌的:请解决这个问题。这将成为即将到来的更新中的一个致命错误。“看起来,使用这样的块会超出图形上下文。 – mpaq