2011-05-04 60 views
16

與400多個頁面中創建PDF文檔,我使用下面的僞代碼來生成PDF文檔:無法在iOS

CGContextRef context = CGPDFContextCreateWithURL(url, &rect, NULL); 

for (int i = 1; i <= N; i++) 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    CGContextBeginPage(context, &mediaBox); 

    // drawing code 

    CGContextEndPage(context); 
    [pool release]; 
} 

CGContextRelease(context); 

它非常好小文件(N < 100頁),但它使用了太多 內存和崩潰如果文檔有超過400頁(它在收到崩潰前收到兩個內存警告 )。我確定使用儀器沒有泄漏。在iOS上創建大型PDF文檔有什麼建議?非常感謝。

編輯:pdf創建是在後臺線程完成。

+0

大問題!我期待看到解決方案。 – 2011-05-04 04:48:44

+0

爲什麼只需要在設備上創建一個大文檔?爲什麼不將數據發送到服務器並在那裏生成PDF文檔? – 2011-05-04 05:02:57

+1

我個人不會考慮通過服務器處理數據,因爲我不認爲每個人都會在他們的iDevices上始終有互聯網連接。 – 2011-05-04 08:28:17

回答

1

如果您分配的內存太多,您的應用程序將崩潰。爲什麼生成一個非常大的PDF是一個目標?你究竟在努力完成什麼?

+0

用戶將1500多頁pdf文檔導入到我的應用中,並使用該應用對其進行了修改並希望將其導出,但我的應用崩潰了... – 2011-05-04 08:20:33

+1

您能否以原始PDF格式開始,只更換已更改的頁面? – 2011-05-12 18:19:14

6

既然你創建通過CGPDFContextCreateWithURL單個文檔的整個事情在內存中舉行,並追加到,一些常用的(雖然我不能肯定與iOS和CGPDFContextCreateWithURL說),需要一個完整的要保存的文件副本。即使沒有前後問題,也不需要泄漏造成問題。

如果你是不是想捕捉一堆現有的UIKit繪製的東西 - 你的樣品中似乎你不是 - 使用OS的印刷方法代替,它提供built-in support for printing to a PDFUIGraphicsBeginPDFContextToFile在添加頁面時將頁面寫入磁盤,因此整個過程不需要一次保存在內存中。你應該能夠以這種方式生成一個巨大的PDF。

+0

UIGraphicsBeginPDFContextToFile線程安全嗎?它沒有在文檔中說,但我會試試看。非常感謝! – 2011-05-04 08:26:23

+0

看來它不太可能線程安全。從概述:「**重要:** UIKit類通常不是線程安全的,所有與圖形相關的操作應該在應用程序的主線程上執行。」 http://developer.apple.com/library/ios/#documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GraphicsDrawingOverview/GraphicsDrawingOverview.html – 2011-05-04 08:32:34

+0

是的,我不希望它很長一段時間阻止主線程...所以這可能對我無效。嘆。 – 2011-05-04 08:49:09

3

可能不是您想要聽到的答案,而是從另一個角度來看它。

您能否認爲它是設備的限制?首先檢查PDF中的頁數,如果它太大,則向用戶發出警告。因此,優雅地處理它。

然後,您可以在此展開....

您可以構建在小的iDevice PDF文件,如果PDF太大,構造它的服務器端下一次的iDevice的淨連接。

1

如何使用內存映射文件來備份CG數據使用者?那麼它不一定要一次裝入RAM。

我創建了一個例子在這裏:https://gist.github.com/3748250

使用方法如下:

NSURL * url = [ NSURL fileURLWithPath:@"pdf.pdf"] ; 
MemoryMappedDataConsumer * consumer = [ [ MemoryMappedDataConsumer alloc ] initWithURL:url ] ; 

CGDataConsumerRef cgDataConsumer = [ consumer CGDataConsumer ] ; 

CGContextRef c = CGPDFContextCreate(cgDataConsumer, NULL, NULL) ; 
CGDataConsumerRelease(cgDataConsumer) ; 

// write your PDF to context `c` 

CGPDFContextClose(c) ; 
CGContextRelease(c) ; 

return 0; 
+0

我想生成超過60頁的PDF,但會導致內存加大。 當我從GITHUB導入後嘗試以上我看到很多像Xcode 7.3中的下面的錯誤----------------- MemoryMappedDataConsumer.m: 功能'munmap'的隱式聲明是無效C99 在需要之前,必須從模塊「Darwin.POSIX.sys.mman」中導入'munmap'的聲明 使用未聲明的標識符'PROT_WRITE''PROT_READ''MAP_SHARED'--------- – Sanju 2016-05-26 12:19:07

+0

嘗試使用'#import ' – nielsbot 2016-05-27 04:35:57