本文授权转载,作者:汉斯哈哈哈(简书)
iOS 开发中总会用到各种缓存,YYCache或许是你最好的选择。性能上有优势,用法也很简单。作者ibireme曾经对比过同类轮子:YYCache 设计思路
1.简单架构图
2.YYCache.h方法分析
@interface YYCache : NSObject // 读取当前数据库名称 @property (copy, readonly) NSString *name; // memoryCache内存缓存,diskCache文件缓存 @property (strong, readonly) YYMemoryCache *memoryCache; @property (strong, readonly) YYDiskCache *diskCache; // 可通过下面三种方法来实例化YYCache对象 – (nullable instancetype)initWithName:(NSString *)name; – (nullable instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER; + (nullable instancetype)cacheWithPath:(NSString *)path; // 禁止通过下面两个方式实例化对象 – (instancetype)init UNAVAILABLE_ATTRIBUTE; + (instancetype)new __attribute__((unavailable(“new方法不可用,请用initWithName:”))); // 通过key判断是否缓存了某个东西,第二个法是异步执行,异步回调 – (BOOL)containsObjectForKey:(NSString *)key; – (void)containsObjectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key, BOOL contains))block; // 读–通过key读取缓存,第二个法是异步执行,异步回调 – (nullable id)objectForKey:(NSString *)key; – (void)objectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key, id object))block; // 增、改–缓存对象(可缓存遵从NSCoding协议的对象),第二个法是异步执行,异步回调 – (void)setObject:(nullable id)object forKey:(NSString *)key; – (void)setObject:(nullable id)object forKey:(NSString *)key withBlock:(nullable void(^)(void))block; // 删–删除缓存 – (void)removeObjectForKey:(NSString *)key; – (void)removeObjectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key))block; – (void)removeAllObjects; – (void)removeAllObjectsWithBlock:(void(^)(void))block; – (void)removeAllObjectsWithProgressBlock:(nullable void(^)(int removedCount, int totalCount))progress endBlock:(nullable void(^)(BOOL error))end; @end3.YYCache使用
// 0.初始化YYCache YYCache *cache = [YYCache cacheWithName:@”mydb”]; // 1.缓存普通字符 [cache setObject:@”汉斯哈哈哈” forKey:@”name”]; NSString *name = (NSString *)[cache objectForKey:@”name”]; NSLog(@”name: %@”, name); // 2.缓存模型 [cache setObject:(id)model forKey:@”user”]; // 3.缓存数组 NSMutableArray *array = @.mutableCopy; for (NSInteger i = 0; i打印:
2016-06-09 11:35:44.069 YYCache源码分析[13546:949048] {number = 2, name = (null)} 2016-06-09 11:35:44.069 YYCache源码分析[13546:949048] array缓存完成…. 2016-06-09 11:35:44.386 YYCache源码分析[13546:949052] {number = 3, name = (null)} 2016-06-09 11:35:44.386 YYCache源码分析[13546:949052] ( “”, “”, “”, “”, “”, “”, “”, “”, “”, “” ) // 缓存实现,默认同时进行内存缓存与文件缓存 – (void)setObject:(id)object forKey:(NSString *)key { [_memoryCache setObject:object forKey:key]; [_diskCache setObject:object forKey:key]; } // 如果只想内存缓存,可以直接调用`memoryCache`对象 YYCache *cache2 = [YYCache cacheWithName:@”mydb”]; [cache2.memoryCache setObject:@24 forKey:@”age”]; NSLog(@”age缓存在内存:%d”, [cache2.memoryCache containsObjectForKey:@”age”]); NSLog(@”age缓存在文件:%d”, [cache2.diskCache containsObjectForKey:@”age”]);打印:
2016-06-09 21:23:24.326 YYCache源码分析[14512:1085375] age缓存在内存:1 2016-06-09 21:23:24.326 YYCache源码分析[14512:1085375] age缓存在文件:04.YYCache.h tips
#if __has_include #import #import #import #elif __has_include #import #import #import #else #import “YYMemoryCache.h” #import “YYDiskCache.h” #import “YYKVStorage.h” #endif__has_include:用来检查Frameworks是否引入某个类,
像YYWebImage已经集成YYCache,如果导入过YYWebImage则无需重新导入YYCache
NS_ASSUME_NONNULL_BEGIN @interface YYCache : NSObject … – (nullable instancetype)initWithName:(NSString *)name; … @end NS_ASSUME_NONNULL_END接口中 nullable 的是少数,一般都为nonnull,为了防止写一大堆 nonnull,Foundation供了一对宏NS_ASSUME_NONNULL_BEGIN、NS_ASSUME_NONNULL_END,包在里面的对象默认加 nonnull 修饰符,如果是nullable的,只需要把 nullable 的指出来就行
– (instancetype)init UNAVAILABLE_ATTRIBUTE; + (instancetype)new UNAVAILABLE_ATTRIBUTE;command+鼠标左键UNAVAILABLE_ATTRIBUTE,
发现宏定义#define UNAVAILABLE_ATTRIBUTE __attribute__((unavailable)),
__attribute__是Clang提供的一种源码注解,方便开发者向编译器表达某种要求,括号里是传达某种命令.
为方便使用,一些常用属性也被Cocoa定义成宏,
比如UNAVAILABLE_ATTRIBUTE、NS_CLASS_AVAILABLE_IOS(9_0).
unavailable告诉编译器该方法失效.
在封装单例或初始化某个类前必须做一些事时,对一些方法禁用是非常不错的选择.
还可以给个message提示:
+ (instancetype)alloc __attribute__((unavailable(“alloc方法不可用,请用initWithName:”))); – (instancetype)init __attribute__((unavailable(“init方法不可用,请用initWithName:”))); + (instancetype)new __attribute__((unavailable(“new方法不可用,请用initWithName:”))); – (instancetype)copy __attribute__((unavailable(“copy方法不可用,请用initWithName:”)));本文只是简单剖析,接下来会分析YYMemoryCache实现原理.
References
http://blog.sunnyxx.com/2016/05/14/clang-attributes/
http://blog.sunnyxx.com/2015/06/12/objc-new-features-in-2015/