Quartz PDF API que causa fallas de memoria
Tengo problemas de bloqueo al utilizar la API Quartz PDF para iOS. En este momento estoy compilando con el SDK 4.0 GM Seed y ejecutándolo en mi iPad 3.2 (he intentado usar el 3.2 SDK con resultados idénticos).
Todo el código que estoy usando se basa en la documentación estándar de Apple Quartz y de varias fuentes alrededor de Internet. Así que no puedo imaginar que estoy haciendo algo drásticamente diferente o incorrecto.
El código se ejecuta perfectamente en el simulador (todas las versiones, es una aplicación universal) e incluso mientras se utiliza la función "Advertencia de memoria simulada". He usado la herramienta Fugas y no hay fugas que encuentre. Build and Analyze tampoco encuentra nada. No se deja ningún bloqueo o registro de memoria baja en mi biblioteca.
Todo esto me lleva a creer que el dispositivo se está quedando sin memoria. Esto sucede después de recorrer, por ejemplo, 50 páginas pdf, con aproximadamente el 35% con una imagen de algún tipo (alguna página completa, algún ícono). No se bloquea en ninguna página en particular. El pdf que estoy cargando es de aproximadamente 75 páginas y 3.5MB.
He leído problemas similares en este sitio y alrededor de Internet, y he aplicado algunos de los consejos en el siguiente código. Ahora libero la referencia del documento pdf en cada vuelta de página y ya no conservo / libero una referencia de página. También he simplificado el intercambio de imágenes de usar CGImages a solo usar la función UIGraphicsGetImageFromCurrentImageContext. He intentado varias implementaciones para cambiar las imágenes, incluido el reemplazo completo de pdfImgView con una instancia temporal recién asignada (usando[[UIImageView alloc] iniWithImage:UIGraphicsGetImageFromCurrentImageContext()]
), usando el setter para pdfImgView y liberando la temp. Todas las variaciones pasan las pruebas de fugas y analizador, pero aún exhiben el mismo comportamiento de bloqueo.
Entonces, antes de alejarme por completo de los archivos PDF, ¿hay algo que debería probar o algo que me falta?
Vea el código del controlador que se llama en los controladores de interfaz para intercambiar páginas y en la primera carga:
[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();
Método drawPage utilizado para configurar y dibujar una página PDF al contexto:
[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;