2011-01-12 25 views
7

Đối với trình đọc PDF, tôi muốn chuẩn bị tài liệu bằng cách chụp 'ảnh chụp màn hình' của mỗi trang và lưu chúng vào đĩa. Phương pháp đầu tiên làNhững gì (tf) là những bí mật đằng sau cấp phát bộ nhớ PDF (CGPDFDocumentRef)

CGPDFDocumentRef document = CGPDFDocumentCreateWithURL((CFURLRef) someURL); 
for (int i = 1; i<=pageCount; i++) 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];  
    CGPDFPageRef page = CGPDFDocumentGetPage(document, i); 
    ...//getting + manipulating graphics context etc. 
    ... 
    CGContextDrawPDFPage(context, page); 
    ... 
    UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext(); 
    ...//saving the image to disc 
    [pool drain]; 
} 
CGPDFDocumentRelease(document); 

Điều này dẫn đến nhiều bộ nhớ mà dường như không được phát hành sau khi chạy đầu tiên của vòng lặp (chuẩn bị các tài liệu 1), nhưng bộ nhớ không chưa được phát hành ở thêm chạy:

MEMORY BEFORE:   6 MB 
MEMORY DURING 1ST DOC: 40 MB 
MEMORY AFTER 1ST DOC: 25 MB 
MEMORY DURING 2ND DOC: 40 MB 
MEMORY AFTER 2ND DOC: 25 MB 
.... 

thay đổi mã để

for (int i = 1; i<=pageCount; i++) 
{ 
    CGPDFDocumentRef document = CGPDFDocumentCreateWithURL((CFURLRef) someURL); 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];  
    CGPDFPageRef page = CGPDFDocumentGetPage(document, i); 
    ...//getting + manipulating graphics context etc. 
    ... 
    CGContextDrawPDFPage(context, page); 
    ... 
    UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext(); 
    ...//saving the image to disc 
    CGPDFDocumentRelease(document); 
    [pool drain]; 
} 

thay đổi việc sử dụng bộ nhớ để

MEMORY BEFORE:   6 MB 
MEMORY DURING 1ST DOC: 9 MB 
MEMORY AFTER 1ST DOC: 7 MB 
MEMORY DURING 2ND DOC: 9 MB 
MEMORY AFTER 2ND DOC: 7 MB 
.... 

nhưng rõ ràng là một bước lùi về hiệu suất.

Khi tôi bắt đầu đọc một PDF (sau này trong thời gian, chủ đề khác nhau) trong trường hợp đầu tiên không có bộ nhớ được cấp phát (ở mức 25 MB), trong khi bộ nhớ thứ hai lên đến 20 MB (từ 7).

Trong cả hai trường hợp, khi tôi xóa bộ nhớ dòng CGContextDrawPDFPage(context, page); là (gần) không đổi ở mức 6 MB trong và sau khi chuẩn bị xong tài liệu.

Ai có thể giải thích những gì đang diễn ra ở đó không?

Trả lời

4

CGPDFTài liệu lưu trữ khá mạnh mẽ và bạn có rất ít quyền kiểm soát điều đó, ngoài - như bạn đã làm - phát hành tài liệu và tải lại từ đĩa.

Lý do bạn không thấy nhiều phân bổ khi bạn xóa cuộc gọi CGContextDrawPDFPage là thạch anh tải tài nguyên trang một cách lười biếng. Khi bạn chỉ cần gọi CGPDFDocumentGetPage, tất cả những gì xảy ra là nó tải một số siêu dữ liệu cơ bản, như giới hạn hộp và chú thích (rất nhỏ trong bộ nhớ).

Phông chữ, hình ảnh, v.v. chỉ được tải khi bạn thực sự vẽ trang - nhưng sau đó chúng được giữ lại trong một thời gian tương đối dài trong bộ đệm trong. Điều này có nghĩa là làm cho hiển thị nhanh hơn, vì tài nguyên trang thường được chia sẻ giữa nhiều trang. Ngoài ra, việc hiển thị một trang nhiều lần là khá phổ biến (ví dụ: khi phóng to). Bạn sẽ nhận thấy rằng việc hiển thị trang lần thứ hai nhanh hơn đáng kể.

+0

Cảm ơn bạn, hợp lý với tôi, vì vậy tôi đã đánh dấu nó là "đúng" mà không thực sự chứng minh điều đó. –

+1

Hi omz.Cảm ơn bạn đã giải thích chi tiết.Tôi có vấn đề tương tự, việc sử dụng bộ nhớ tăng lên đáng kể khi tôi tiếp tục hiển thị các trang và ứng dụng bị lỗi sau một số thời điểm. Tôi đang sử dụng PDFDocument riêng cho mỗi trang (chỉ chứa một trang) được tạo và phát hành trong drawLayer: inContext: method.please cho tôi đề xuất để tránh tự động lưu vào bộ nhớ cache của nội dung trang và giảm mức sử dụng bộ nhớ. – Hariprasad

+0

@Hariprasad Tôi có một vấn đề tương tự với bạn. Và tôi không thể tìm ra giải pháp nào ngoài đó. Một số người nói rằng lỗi của khung công tác khác là phát hành, nhưng tôi nghĩ rằng tôi đã phát hành mọi thứ. Tôi không có rò rỉ hoặc bất cứ điều gì và vẫn còn tại một số điểm sẽ sụp đổ. Bạn đã tìm thấy một giải pháp cho điều này? – otakuProgrammer

Các vấn đề liên quan