在SDWebImageCompat中的.h文件中,主要都是定义的一些开关,包括对iphone、mac、watchTv等设备的开关等。
在里面看到关于线程的一段比较好的代码
#ifndef dispatch_queue_async_safe
#define dispatch_queue_async_safe(queue, block)\
if (dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) == dispatch_queue_get_label(queue)) {\
block();\
} else {\
dispatch_async(queue, block);\
}
#endif
#ifndef dispatch_main_async_safe
#define dispatch_main_async_safe(block) dispatch_queue_async_safe(dispatch_get_main_queue(), block)
#endif
关于这段代码的含义,可以参考https://www.jianshu.com/p/bdbc7d6618a3
接下来开始看SDWebImageCompat.m中的代码
在.m文件中只有一个方法
inline UIImage *SDScaledImageForKey(NSString * _Nullable key, UIImage * _Nullable image) {
if (!image) {
return nil;
}
//如果设备是mac,则直接返回image对象
#if SD_MAC
return image;
#elif SD_UIKIT || SD_WATCH
if ((image.images).count > 0) {
NSMutableArray<UIImage *> *scaledImages = [NSMutableArray array];
for (UIImage *tempImage in image.images) {
// 这部分又调用了这个方法,每次就是image.images中的每一个走一遍这个方法,然后scaledImages执行相应的addObject,这部分相当于递归了
[scaledImages addObject:SDScaledImageForKey(key, tempImage)];
}
UIImage *animatedImage = [UIImage animatedImageWithImages:scaledImages duration:image.duration];
if (animatedImage) {
//给动态图片的属性赋值,这两个属性是写在UIImage的分类中,文件名为UIImage + MultiFormat中
animatedImage.sd_imageLoopCount = image.sd_imageLoopCount;
animatedImage.sd_imageFormat = image.sd_imageFormat;
}
return animatedImage;
} else {
#if SD_WATCH
if ([[WKInterfaceDevice currentDevice] respondsToSelector:@selector(screenScale)]) {
#elif SD_UIKIT
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
#endif
CGFloat scale = 1;
if (key.length >= 8) {
NSRange range = [key rangeOfString:@"@2x."];
if (range.location != NSNotFound) {
scale = 2.0;
}
range = [key rangeOfString:@"@3x."];
if (range.location != NSNotFound) {
scale = 3.0;
}
}
if (scale != image.scale) {
UIImage *scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation];
scaledImage.sd_imageFormat = image.sd_imageFormat;
image = scaledImage;
}
}
return image;
}
#endif
}
网友评论