应用场景:
- 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
引用,不是拷贝,在清理的时候计算的是实际大小而不是引用的大小