Mi programa muestra una superficie de desplazamiento horizontal de azulejos con UIImageViews de izquierda a derecha. Código se ejecuta en el subproceso de interfaz de usuario para asegurarse de que UIImageViews recién visibles tienen un UIImage recién cargado asignado a ellos. La carga ocurre en un hilo de fondo.CGImage/UIImage perezosamente de carga en el hilo de interfaz de usuario hace que tartamudeo
Todo funciona casi bien, excepto que hay un tartamudeo cuando cada imagen se vuelve visible. Al principio, pensé que mi asistente social estaba bloqueando algo en el hilo de la interfaz de usuario. Pasé mucho tiempo mirando y finalmente se dio cuenta de que el UIImage está haciendo un proceso adicional de descanso en el hilo de interfaz de usuario cuando por primera vez se hace visible. Esto me desconcierta, ya que mi hilo de trabajo tiene un código explícito para descomprimir datos JPEG.
De todos modos, por un presentimiento escribí un código para procesar en un contexto de gráficos temporales en el hilo de fondo y, efectivamente, el tartamudeo desapareció. El UIImage ahora está siendo precargado en mi hilo de trabajo. Hasta aquí todo bien.
El problema es que mi nuevo método de "forzar la carga lenta de la imagen" no es confiable. Causa intermitente EXC_BAD_ACCESS. No tengo idea de qué hace realmente UIImage entre bastidores. Quizás esté descomprimiendo los datos JPEG. De todos modos, el método es:
+ (void)forceLazyLoadOfImage: (UIImage*)image
{
CGImageRef imgRef = image.CGImage;
CGFloat currentWidth = CGImageGetWidth(imgRef);
CGFloat currentHeight = CGImageGetHeight(imgRef);
CGRect bounds = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
CGAffineTransform transform = CGAffineTransformIdentity;
CGFloat scaleRatioX = bounds.size.width/currentWidth;
CGFloat scaleRatioY = bounds.size.height/currentHeight;
UIGraphicsBeginImageContext(bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextScaleCTM(context, scaleRatioX, -scaleRatioY);
CGContextTranslateCTM(context, 0, -currentHeight);
CGContextConcatCTM(context, transform);
CGContextDrawImage(context, CGRectMake(0, 0, currentWidth, currentHeight), imgRef);
UIGraphicsEndImageContext();
}
Y el EXC_BAD_ACCESS sucede en la línea CGContextDrawImage. PREGUNTA 1: ¿Se me permite hacer esto en un hilo que no sea el del UI? PREGUNTA 2: ¿Qué es realmente el UIImage "precargado"? PREGUNTA 3: ¿Cuál es la forma oficial de resolver este problema?
Gracias por leer todo eso, cualquier consejo sería muy apreciada!
hola, gracias por tomarse el tiempo para ayudar con esto. Finalmente llegué a esta comprensión. Solo puedo imaginar qué tipo de almacenamiento en caché desagradable no es seguro para los hilos dentro de esos métodos UI *. Mi interfaz ahora está libre de traumas ... – JBx
Estoy confundido ... ¿Estás diciendo que imageNamed: está causando IO de archivos vagos pero ... la creación de un objeto de datos no? ¿O está diciendo que debería tener los objetos de datos agrupados en algún lugar para extraerlos cuando corresponda? –
Jasconius: si crea un objeto UIImage y le da la ruta a un archivo, es posible que no cargue toda la imagen en la memoria hasta que la dibuje. Si carga el archivo en la memoria utilizando un objeto NSData, luego pase eso a UIImage, no tiene más remedio que guardarlo en la memoria. Lo mejor depende de la situación específica. – benzado