Невозможно создать PDF-документ с более чем 400 страницами на iOS
Я использую следующий псевдокод для создания PDF-документа:
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
pages), но он использует слишком много
памяти и сбоев, если документ содержит более 400 страниц (он получил
два предупреждения памяти перед сбоем.) Я убедился, что утечек не было
Инструменты. Каковы ваши советы по созданию больших PDF-документов на iOS? Большое спасибо.
edit: Создание PDF выполняется в фоновом потоке.
Ответы
Ответ 1
Поскольку вы создаете один документ с помощью CGPDFContextCreateWithURL
, вся вещь должна храниться в памяти и прилагаться к ней, то, что обычно (хотя я не могу сказать наверняка с iOS и CGPDFContextCreateWithURL
), требует полного до и после копии документа, который необходимо сохранить. Нет необходимости в утечке, чтобы создать проблему, даже без проблем до и после.
Если вы не пытаетесь захватить кучу существующего материала UIKit - и в вашем примере кажется, что вы не используете, вместо этого используйте методы печати ОС, которые предлагают встроенная поддержка печати в PDF. UIGraphicsBeginPDFContextToFile
записывает страницы на диск, поскольку они добавлены, поэтому все это не обязательно должно храниться в памяти сразу. Вы должны иметь возможность генерировать огромный PDF таким образом.
Ответ 2
Вероятно, это не тот ответ, который вы хотите услышать, но глядя на него с другой точки зрения.
Не могли бы вы считать это ограничением устройства?... Сначала проверьте количество страниц в PDF и, если оно слишком велико, предоставьте пользователю предупреждение. Поэтому обрабатывайте его изящно.
Затем вы можете расширить это...
Вы можете создать небольшой PDF файл на iDevice, и если PDF слишком велик, создайте его на стороне сервера в следующий раз, когда iDevice будет иметь сетевое соединение.
Ответ 3
Если вы выделяете слишком много памяти, ваше приложение выйдет из строя. Почему создается необычно большой PDF файл? Что вы на самом деле пытаетесь выполнить?
Ответ 4
Как насчет использования файла с отображением памяти для резервного копирования вашего пользователя данных CG? Тогда он не обязательно должен сразу вставляться в ОЗУ.
Я создал пример здесь: 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;