¿Por qué este código descomprime un UIImage mucho mejor que el enfoque ingenuo?

En mi aplicación necesito cargar imágenes JPEG grandes y mostrarlas en una vista de desplazamiento. Para mantener la interfaz de usuario sensible, decidí cargar las imágenes en segundo plano, luego mostrarlas en el hilo principal. Para cargarlos completamente en segundo plano, presiono cada image para que se descomprima. Estaba usando este código para descomprimir una image (tenga en count que mi aplicación es solo iOS 7, así que entiendo que usar estos methods en un subprocess de background es correcto):

+ (UIImage *)decompressedImageFromImage:(UIImage *)image { UIGraphicsBeginImageContextWithOptions(image.size, YES, 0); [image drawAtPoint:CGPointZero]; UIImage *decompressedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return decompressedImage; } 

Sin embargo, todavía tenía times de carga prolongados, tartamudeo UI y mucha presión de memory. Acabo de encontrar otra solución :

 + (UIImage *)decodedImageWithImage:(UIImage *)image { CGImageRef imageRef = image.CGImage; // System only supports RGB, set explicitly and prevent context error // if the downloaded image is not the supported format CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef), 8, // width * 4 will be enough because are in ARGB format, don't read from the image CGImageGetWidth(imageRef) * 4, colorSpace, // kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little // makes system don't need to do extra conversion when displayed. kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little); CGColorSpaceRelease(colorSpace); if ( ! context) { return nil; } CGRect rect = (CGRect){CGPointZero, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)}; CGContextDrawImage(context, rect, imageRef); CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context); CGContextRelease(context); UIImage *decompressedImage = [[UIImage alloc] initWithCGImage:decompressedImageRef]; CGImageRelease(decompressedImageRef); return decompressedImage; } 

Este código es de order de magnitud mejor. La image se carga casi de inmediato, no hay tartamudeo UI, y el uso de la memory ha ido muy lejos.

Entonces, mi pregunta es doble:

  1. ¿Por qué el segundo método es mucho mejor que el primero?
  2. Si el segundo método es mejor debido a los parameters únicos del dispositivo, ¿hay alguna manera de garantizar que funcione igual de bien para todos los dispositivos iOS, presentes y futuros? No quisiera asumir un formatting de bitmap nativo que cambie en mí, reintroduciendo este problema.

Supongo que estás ejecutando esto en un dispositivo Retina. En UIGraphicsBeginImageContextWithOptions , solicitó la escala pnetworkingeterminada, que es la escala de la pantalla principal, que es 2. Esto significa que está generando un bitmap 4x tan grande. En la segunda function, estás dibujando en una escala de 1x.

Intente pasar una escala de 1 a UIGraphicsBeginImageContextWithOptions y vea si su performance es similar.