应用场景:
- 1.通过
UIColor生成一个UIImage,并缓存起来,这样,如果下次传同一个color就不用通过代码再次创建,直接从缓存中读取UIImage - 2.程序被杀死后,缓存被清除(考虑NSCache)
代码
#import <UIKit/UIKit.h>
@interface UIImage (NTESColor)
+ (UIImage *)imageWithColor:(UIColor *)color;
@end
#import <sys/stat.h>
#import "UIImage+NTESColor.h"
@interface UIColorCache : NSObject
@property (nonatomic,strong) NSCache *colorImageCache;
@end
@implementation UIColorCache
+ (instancetype)sharedCache{
static UIColorCache *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[UIColorCache alloc] init];
});
return instance;
}
- (instancetype)init{
if (self = [super init]){
_colorImageCache = [[NSCache alloc] init];
}
return self;
}
- (UIImage *)image:(UIColor *)color{
return color ? [_colorImageCache objectForKey:[color description]] : nil;
}
- (void)setImage:(UIImage *)image
forColor:(UIColor *)color{
[_colorImageCache setObject:image
forKey:[color description]];
}
@end
@implementation UIImage (NTESColor)
+ (UIImage *)clearColorImage {
return [UIImage imageNamed:@"Clear_color_image"];
}
+ (UIImage *)imageWithColor:(UIColor *)color {
if (color == nil) {
assert(0);
return nil;
}
UIImage *image = [[UIColorCache sharedCache] image:color];
if (image == nil){
CGFloat alphaChannel;
[color getRed:NULL green:NULL blue:NULL alpha:&alphaChannel];
BOOL opaqueImage = (alphaChannel == 1.0);
CGRect rect = CGRectMake(0, 0, 1, 1);
UIGraphicsBeginImageContextWithOptions(rect.size, opaqueImage, [UIScreen mainScreen].scale);
[color setFill];
UIRectFill(rect);
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[[UIColorCache sharedCache] setImage:image
forColor:color];
}
return image;
}
@end
代码分析:
- 1.为什么创建单例
UIColorCache?UIColorCache这个单例的colorImageCache缓存color生成的图片 - 2.使用
[color description]作为key确保了唯一性
NSCache简单说明
- 1.
NSCache是苹果官方提供的缓存类,具体使用和NSMutableDictionary类似,在AFN和SDWebImage框架中被使用来管理缓存 - 2.苹果官方解释
NSCache在系统内存很低时,会自动释放对象(但模拟器演示不会释放) 建议:接收到内存警告时主动调用removeAllObject方法释放对象 - 3.
NSCache是线程安全的,在多线程操作中,不需要对NSCache加锁 - 4.
NSCache的Key只是对对象进行Strong引用,不是拷贝,在清理的时候计算的是实际大小而不是引用的大小