2011-05-04 12 views
16

estoy usando el siguiente pseudocódigo para generar un documento PDF:No se puede crear el documento PDF con más de 400 páginas en IOS

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 utiliza demasiada memoria y se bloquea si el documento tiene más de 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 documentos PDF grandes en iOS? Muchas gracias.

editar: La creación de pdf se realiza en una cadena de fondo.

+0

Muy buena pregunta! Espero ver la solución. –

+0

¿Por qué solo necesita un documento grande creado en el dispositivo? ¿Por qué no enviar los datos a un servidor y tener el documento PDF generado allí? –

+1

Personalmente, no consideraría procesar datos de un servidor porque no creo que todos tengan conexión a Internet en sus iDevices todo el tiempo. –

Respuesta

1

Si asigna demasiada memoria, su aplicación se bloqueará. ¿Por qué generar un PDF inusualmente grande es un objetivo? ¿Qué estás realmente tratando de lograr?

+0

Un usuario importó un documento PDF de más de 1500 páginas en mi aplicación, lo modificó utilizando la aplicación y quería exportarlo, pero mi aplicación se bloqueó ... –

+1

¿Podría comenzar tomando el PDF original y simplemente reemplazando las páginas que han cambiado? –

6

Puesto que usted está creando un único documento a través CGPDFContextCreateWithURL toda la cosa tiene que ser mantenido en la memoria y anexado a, algo que normalmente (aunque no puedo decir con certeza con iOS y CGPDFContextCreateWithURL) requerirá una carga completa antes de y después de copia del documento que se mantendrá. No es necesario que una fuga genere un problema, incluso sin el problema de antes y después.

Si usted no está tratando de capturar un montón de cosas UIKit tirados existente - y en la muestra parece que no estás - En lugar de utilizar métodos de impresión del sistema operativo, que ofrecen built-in support for printing to a PDF. UIGraphicsBeginPDFContextToFile escribe las páginas en el disco a medida que se agregan, por lo que no es necesario guardar todo en la memoria a la vez. Debería poder generar un gran PDF de esa manera.

+0

¿Es seguro el subproceso UIGraphicsBeginPDFContextToFile? No dice en los documentos, pero lo probaré. ¡Muchas gracias! –

+0

Parece que no es seguro para subprocesos. Desde la vista general: "** Importante: ** Las clases de UIKit generalmente no son seguras para subprocesos. Todas las operaciones relacionadas con el dibujo deben realizarse en el hilo principal de la aplicación". http://developer.apple.com/library/ios/#documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GraphicsDrawingOverview/GraphicsDrawingOverview.html –

+0

Sí, no quiero que bloquee el hilo principal durante mucho tiempo ... Entonces esto puede no funcionar para mi suspiro. –

3

Probablemente no sea la respuesta que desea 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, advierta al usuario. Por lo tanto, manejarlo con gracia.

A continuación, puede ampliar esto ....

Se podría construir pequeños de PDF en el iDevice y si el PDF es demasiado grande, construirla en el servidor la próxima vez que el iDevice tiene una conexión de red.

1

¿Qué tal el uso de un archivo mapeado en memoria para respaldar su consumidor de datos CG? Entonces, no necesariamente tiene que caber en la memoria RAM de una sola vez.

creé un ejemplo aquí: https://gist.github.com/3748250

utilizar de esta manera:

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; 
+0

Quiero generar PDF más de 60 páginas, pero se bloquea con la elevación de la memoria. cuando intenté arriba después de importar desde GITHUB Veo tantos errores como a continuación en Xcode 7.3 ----------------- MemoryMappedDataConsumer.m: La declaración implícita de la función 'munmap' es no válido en C99 La declaración de 'munmap' se debe importar desde el módulo 'Darwin.POSIX.sys.mman' antes de que sea necesaria Uso del identificador no declarado 'PROT_WRITE' 'PROT_READ' 'MAP_SHARED' --------- – Sanju

+0

intente utilizar '# import ' – nielsbot

Cuestiones relacionadas