Warum dekomprimiert dieser Code ein UIImage so viel besser als der naive Ansatz?

In meiner App muss ich große JPEG-Bilder laden und sie in einer Bildlaufansicht anzeigen. Um die Benutzeroberfläche ansprechend zu halten, habe ich mich entschlossen, die Bilder im Hintergrund zu laden und sie dann im Haupt-Thread anzuzeigen. Um sie im Hintergrund vollständig zu laden, muss jedes Bild dekomprimiert werden. ichwar Verwenden dieses Codes zum Dekomprimieren eines Bildes (Beachten Sie, dass meine App nur iOS 7 ist. Daher ist die Verwendung dieser Methoden in einem Hintergrundthread in Ordnung):

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

Ich hatte jedoch immer noch lange Ladezeiten, ein Ruckeln der Benutzeroberfläche und viel Speicherdruck. Ich habe gerade gefundeneine andere Lösung:

+ (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;
}

Dieser Code ist um Größenordnungen besser. Das Bild wird fast sofort geladen, die Benutzeroberfläche stottert nicht und die Speichernutzung ist erheblich gesunken.

Meine Frage ist also zweifach:

Warum ist die zweite Methode so viel besser als die erste?Wenn die zweite Methode aufgrund der eindeutigen Parameter des Geräts besser ist, gibt es eine Möglichkeit, sicherzustellen, dass sie für alle gegenwärtigen und zukünftigen iOS-Geräte gleich gut funktioniert? Ich möchte kein natives Bitmap-Format annehmen, das sich bei mir ändert, wodurch dieses Problem erneut auftritt.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage