Подтвердить что ты не робот

Невозможно создать 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 выполняется в фоновом потоке.

4b9b3361

Ответ 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;