2014-12-19 23 views
5

Mam problem z metodą eksportu do formatu PDF, która działała bez zarzutu, aż do momentu przeniesienia aplikacji do architektury arm64.UIGraphicsBeginPDFPage() losowo zawiesza się na urządzeniach 64-bitowych (CGPDFSecurityManagerCreateDecryptor())

W wersji binarnej metoda otwiera istniejący plik PDF, tworzy nowy plik pdf i rysuje zawartość pierwszego pliku PDF do nowo utworzonego pliku przed dodaniem kolejnych stron zawartości.

Gdy metoda próbuje utworzyć nową stronę pdf do dokumentu (po tym, jak pierwszy plik PDF został zintegrowany z nowym plikiem pdf), aplikacja ulega awarii z ostrzeżeniem EXC_BAD_ACCESS na UIGraphicsBeginPDFPage(); połączenie .

Dzieje się tak tylko w przypadku niektórych plików PDF, a nie wszystkich i tylko w urządzeniach 64-bitowych.

Oto stacktrace, który pokazuje wywołanie CGPDFSecurityManagerCreateDecryptor(), którego nie mogłem znaleźć.

Thread 14Queue : NSOperationQueue 0x14f6dd3a0 :: NSOperation 0x17504a470 (serial) 
#0  0x00000001838aeee4 in CGPDFSecurityManagerCreateDecryptor() 
#1  0x00000001838d1004 in pdf_filter_chain_create() 
#2  0x0000000183831e00 in CGPDFStreamCreateFilterChain() 
#3  0x000000018383226c in chain_get_bytes() 
#4  0x0000000183b5e0ac in unpackImageRow() 
#5  0x0000000183b5dfd4 in PDFImageEmitData() 
#6  0x0000000183b5f684 in emit_image() 
#7  0x0000000183b5ef9c in PDFImageEmitDefinition() 
#8  0x0000000183464584 in __CFSetApplyFunction_block_invoke() 
#9  0x00000001834643bc in CFBasicHashApply() 
#10  0x00000001834642e4 in CFSetApplyFunction() 
#11  0x0000000183b5fa9c in PDFImageSetEmitDefinitions() 
#12  0x0000000183b590c0 in emit_page_resources(PDFDocument*)() 
#13  0x0000000183b5904c in PDFDocumentEndPage() 
#14  0x0000000183b57cf0 in pdf_EndPage() 
#15  0x0000000187fda904 in UIGraphicsBeginPDFPageWithInfo() 
#16  0x00000001002093e8 in -[ExportTools renderPdfContentToContext:forPlanVersion:] 
#17  0x00000001001fba60 in -[ExportTools generatePdfReportWithOptions:] 
#18  0x00000001000f7eb4 in -[DetailViewController generatePdfAndShowModalOpenWithAppWithOptions:] 
#19  0x00000001835883c0 in __invoking___() 
#20  0x0000000183486138 in -[NSInvocation invoke]() 
#21  0x000000018443ba20 in -[NSInvocationOperation main]() 
#22  0x000000018437c61c in -[__NSOperationInternal _start:]() 
#23  0x000000018443e26c in __NSOQSchedule_f() 
#24  0x000000010105cdf0 in _dispatch_client_callout() 
#25  0x0000000101067854 in _dispatch_queue_drain() 
#26  0x0000000101060120 in _dispatch_queue_invoke() 
#27  0x000000010106975c in _dispatch_root_queue_drain() 
#28  0x000000010106af18 in _dispatch_worker_thread3() 
#29  0x00000001945012e4 in _pthread_wqthread() 

Jeśli masz jakiś pomysł na temat tej katastrofy, Twoja pomoc będzie bardzo mile widziane, był jednym dzień próbuje wszystko, aby rozwiązać ten problem i beggening się zastanawiać, czy to nie jest bug UIKit ...

Dzięki

+0

Widzę tę samą awarię w tej samej funkcji, ale z innym śladem stosu. Chociaż nie napisałem tego oprogramowania, mogę sprawdzić, czy działa on również z dokumentami PDF i działa na OS X 10.10, więc jego 64-bitowy – HairOfTheDog

Odpowiedz

1

miałem awarię na metodzie CGPDFSecurityManagerCreateDecryptor 64-urządzeń tylko za pomocą następującego kodu:

CGPDFDocumentRelease(pdf); 
CGDataProviderRelease(provider); 
UIGraphicsEndPDFContext(); 

CGPDFSecurityManagerCreateDecryptor wo zostaniesz wezwany, gdy zakończysz kontekst. Awaria ustąpiła, gdy zakończyłem kontekst PRZED uwolnieniem dokumentu i dostawcy.

UIGraphicsEndPDFContext(); 
CGPDFDocumentRelease(pdf); 
CGDataProviderRelease(provider); 
0

Ja też borykałem się z tym samym problemem i podczas gdy odpowiedź Billa podpowiadała mi, że muszę zrobić to trochę inaczej. W mojej sytuacji istnieje zmienna liczba źródłowych plików PDF, które są kopiowane do docelowego pliku PDF, więc nie mogę po prostu przenieść UIGraphicsEndContext przed CGPDFDocumentRelease. Struktura kod wygląda mniej więcej tak:

UIGraphicsBeginPDFContextToFile(...); 
// ... 
for each attachment pdf { 
    srcPdf = CGPDFDocumentCreateWithURL(...); // open source PDF 
    // ... 
    UIGraphicsBeginPDFPageWithInfo(...); // new page in target PDF, this randomly crashes 
    // ... 
    CGPDFDocumentRelease(srcPdf); // close source PDF 
} 
// ... 
UIGraphicsEndPDFContext(); 

Zamiast więc starałem uchwycenie odnośniki do wszystkich plików PDF to źródłowych używanych i uwalniając je wszystkie po resztę docelowego PDF odbywa się znacznie później w kodzie. Jest to brzydkie, ponieważ przenosi odpowiedzialność daleko i utrzymuje całą pamięć do końca, zamiast zwalniać po każdym renderowaniu ... ALE wydaje się działać! Trudno powiedzieć jednoznacznie, bo to była przypadkowa awaria, ale od tamtej pory jej nie widziałem, a ja bardzo ją uderzałem, próbując ją powtórzyć.

pdfRefs = [[NSPointerArray alloc] init]; 
UIGraphicsBeginPDFContextToFile(...); 
// ... 
for each attachment pdf { 
    srcPdf = CGPDFDocumentCreateWithURL(...); // open source PDF 
    // ... 
    UIGraphicsBeginPDFPageWithInfo(...); // new page in target PDF, this randomly crashes 
    // ... 
    [pdfRefs addPointer:srcPdf]; // store for later closing 
} 
// ... 
UIGraphicsEndPDFContext(); 
for each srcPdf in pdfRefs { 
    CGPDFDocumentRelease(srcPdf); // close it here 
}