No se puede crear un documento PDF con más de 400 páginas en iOS
objective-c pdf-generation (4)
Estoy utilizando el siguiente pseudocódigo para generar un documento 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);
Funciona muy bien con documentos pequeños ( N < 100
páginas), pero usa demasiada memoria y se bloquea si el documento tiene más de aproximadamente 400 páginas (recibió dos advertencias de memoria antes de fallar). Me he asegurado de que no haya fugas usando Instrumentos ¿Cuál es su consejo sobre la creación de grandes documentos PDF en iOS? Muchas gracias.
Editar: La creación de PDF se realiza en un hilo de fondo.
¿Qué pasa con el uso de un archivo mapeado en memoria para respaldar a su consumidor de datos CG? Entonces no necesariamente tiene que caber en la memoria RAM de una vez.
He creado un ejemplo aquí: https://gist.github.com/3748250
Úsalo así:
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;
Dado que está creando un solo documento a través de CGPDFContextCreateWithURL
todo debe CGPDFContextCreateWithURL
en la memoria y agregarse, algo que comúnmente (aunque no puedo decir con seguridad con iOS y CGPDFContextCreateWithURL
) requiere una copia completa antes y después del documento. para ser guardado. No hay necesidad de una fuga para crear un problema, incluso sin el problema del antes y el después.
Si no está intentando capturar un montón de elementos existentes dibujados por UIKit (y en su muestra parece que no lo está), utilice los métodos de impresión del sistema operativo en su lugar, que ofrecen soporte integrado para imprimir en un PDF . UIGraphicsBeginPDFContextToFile
escribe las páginas en el disco a medida que se agregan para que todo el contenido no tenga que UIGraphicsBeginPDFContextToFile
en la memoria de una vez. Deberías poder generar un PDF enorme de esa manera.
Probablemente no sea la respuesta que quieres escuchar, pero mirándola desde otra perspectiva.
¿Podría considerarlo como una limitación del dispositivo? ... Primero verifique el número de páginas en el PDF y, si es demasiado grande, avise al usuario. Por lo tanto manejándolo con gracia.
Entonces podrías expandir esto ...
Podría construir PDFs pequeños en el iDevice y si el PDF es demasiado grande, constrúyalo del lado del servidor la próxima vez que el iDevice tenga una conexión de red.
Si asignas demasiada memoria, tu aplicación se bloqueará. ¿Por qué generar un PDF inusualmente grande es un objetivo? ¿Qué estás tratando de lograr realmente?