在之前我们做图片异步加载的时候经常会遇到在滑动tableView的时候卡顿的情况,但是我们确实是在子线程下载并创建UIImage对象然后才在主线程进行现实的,而用SDWebImage的时候就不会卡呢,其实仔细研究一下它的代码就很容易发现了:
#import "SDWebImageDecoder.h" @implementation UIImage (ForceDecode) + (UIImage *)decodedImageWithImage:(UIImage *)image { if (image.images) { // Do not decode animated images return image; } CGImageRef imageRef = image.CGImage; CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); CGRect imageRect = (CGRect){.origin = CGPointZero, .size = imageSize}; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); int infoMask = (bitmapInfo & kCGBitmapAlphaInfoMask); BOOL anyNonAlpha = (infoMask == kCGImageAlphaNone || infoMask == kCGImageAlphaNoneSkipFirst || infoMask == kCGImageAlphaNoneSkipLast); // CGBitmapContextCreate doesn‘t support kCGImageAlphaNone with RGB. // https://developer.apple.com/library/mac/#qa/qa1037/_index.html if (infoMask == kCGImageAlphaNone && CGColorSpaceGetNumberOfComponents(colorSpace) > 1) { // Unset the old alpha info. bitmapInfo &= ~kCGBitmapAlphaInfoMask; // Set noneSkipFirst. bitmapInfo |= kCGImageAlphaNoneSkipFirst; } // Some PNGs tell us they have alpha but only 3 components. Odd. else if (!anyNonAlpha && CGColorSpaceGetNumberOfComponents(colorSpace) == 3) { // Unset the old alpha info. bitmapInfo &= ~kCGBitmapAlphaInfoMask; bitmapInfo |= kCGImageAlphaPremultipliedFirst; } // It calculates the bytes-per-row based on the bitsPerComponent and width arguments. CGContextRef context = CGBitmapContextCreate(NULL, imageSize.width, imageSize.height, CGImageGetBitsPerComponent(imageRef), 0, colorSpace, bitmapInfo); CGColorSpaceRelease(colorSpace); // If failed, return undecompressed image if (!context) return image; CGContextDrawImage(context, imageRect, imageRef); CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context); CGContextRelease(context); UIImage *decompressedImage = [UIImage imageWithCGImage:decompressedImageRef scale:image.scale orientation:image.imageOrientation]; CGImageRelease(decompressedImageRef); return decompressedImage; } @end
在子线程中,SD已经获取了UIImage对象,但是他不是直接将图片展示出来,而是进行了如下操作,获得了一个新的UIImage对象,其实这个过程就是对图像数据进行了解压,如果不这样做,这个过程将会在现实图像的时候在主线程中进行。so……
时间: 2024-11-01 19:34:31