Quartz PDF API, вызывающий сбои памяти - PullRequest
2 голосов
/ 22 июня 2010

У меня возникают проблемы с использованием Quartz PDF API для iOS. В настоящий момент я компилирую с SDK 4.0 GM Seed и работаю на своем 3.2 iPad (я пытался использовать 3.2 SDK с идентичными результатами).

Весь код, который я использую, основан на стандартной документации Apple Quartz и из различных источников в интернете. Поэтому я не могу представить, что делаю что-то радикально другое или неправильное.

Код прекрасно работает в симуляторе (все версии, это универсальное приложение) и даже при использовании функции «Предупреждение о симуляции памяти». Я использовал инструмент Утечки, и нет никаких утечек, которые он находит. Сборка и анализ тоже ничего не находит. В моей библиотеке не осталось сообщений о сбоях или нехватке памяти.

Все это заставляет меня поверить, что устройству не хватает памяти. Это происходит после прохождения, скажем, 50 страниц PDF, причем около 35% имеют какое-то изображение (некоторая полная страница - иконка). Он не падает на какой-либо конкретной странице. Я загружаю в формате PDF около 75 страниц и 3,5 МБ.

Я просматривал похожие проблемы на этом сайте и в интернете и применил некоторые советы из приведенного ниже кода. Теперь я выпускаю ссылку на документ PDF на каждом повороте страницы и больше не сохраняю / не отпускаю ссылку на страницу. Я также упростил обмен изображениями с использования CGImages до простого использования функции UIGraphicsGetImageFromCurrentImageContext. Я пробовал различные реализации для переключения изображений, включая полную замену pdfImgView вновь выделенным временным экземпляром (используя [[UIImageView alloc] iniWithImage:UIGraphicsGetImageFromCurrentImageContext()]), использование установщика для pdfImgView и освобождение временного. Все варианты проходят тесты Leaks и Analyzer, но все равно демонстрируют одинаковое поведение при сбое.

Итак, прежде чем я вообще отойду от PDF-файлов, я должен что-то попробовать или пропустить?

Просмотр кода контроллера, который вызывается в интерфейсных обработчиках для обмена страницами и при первой загрузке:

[self drawPage];

// ...animation code...simple CATransition animation...crashes with or without

// scrollView is a UIScrollView that is a subview of self.view
[scrollView.layer addAnimation:transition forKey:nil];
// pdfImgView is a UIImageView that is a subview of scrollView
pdfImgView.image = UIGraphicsGetImageFromCurrentImageContext();

Метод drawPage, используемый для настройки и отображения страницы PDF в контексте:

[CFURLRef pdfURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("BME_interior.pdf"), NULL, NULL);
pdfRef = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL); // instance variable, not a property
CFRelease(pdfURL);
CGPDFPageRef page = CGPDFDocumentGetPage(pdfRef, currentPage);

CGRect box = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
// ...setting scale and imageHeight, both floats...

if (UIGraphicsBeginImageContextWithOptions != NULL) {
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.view.frame.size.width, imageHeight), NO, 0.0);
} else {
    UIGraphicsBeginImageContext(CGSizeMake(self.view.frame.size.width, imageHeight));
}
CGContextRef context = UIGraphicsGetCurrentContext();
NSLog(@"page is %d, context is %d, pdf doc is %d, pdf page is %d", currentPage, context, pdfRef, page); // all prints properly

// ...setting up scrollView for new page, using same instance...

CGContextTranslateCTM(context, (self.view.frame.size.width-(box.size.width*scale))/2.0f, imageHeight);
CGContextScaleCTM(context, scale, -1.0*scale);

CGContextSaveGState(context);
CGContextDrawPDFPage(context, page);
CGContextRestoreGState(context);

CGPDFDocumentRelease(pdfRef);
pdfRef = NULL;

Ответы [ 2 ]

1 голос
/ 22 июня 2010

Aha! Я исправил сбои, добавив UIGraphicsEndImageContext(); перед началом нового контекста изображения. Я даже не получаю предупреждения памяти сейчас ...

0 голосов
/ 11 августа 2011

Звонок

CGContextSetInterpolationQuality(context, kCGInterpolationHigh); 
CGContextSetRenderingIntent(context, kCGRenderingIntentDefault);

до CGContextDrawPDFPage решил аналогичную мою проблему.

Кредиты идут на этот ответ Иоганна: CGContextDrawPDFPage занимает большой объем памяти

...