2013-11-14 45 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