文章标题

来源:互联网 发布:php 业务逻辑层 编辑:程序博客网 时间:2024/06/04 18:21

YYCache

1. 线程安全

有多重方法可以保证线程安全。TMMemoryCache 在设计时,把所有读写操作都放到了同一个 concurrent queue 中,然后用dispatch_barrier_async 来保证任务能顺序执行,据说这种方法会有多余的线程开销。
YYCache则采用了不同的方式,在memoryCache中采用互斥锁pthread_mutex_t,在DiskCachez中用dispatch_semaphore_t的信号量来保证线程安全,信号量的值设为1,和互斥锁的效果一样。

2. MemoryCache

核心是_YYLinkedMap

  1. 有一个自己实现的双向链表,由_YYLinkedMapNode组成,用LRU算法来实现淘汰算法。Node中存储了最关键的key和value

  2. 用一个dic( 用的是coreFoundation的CFMutableDictionaryRef,
    相对于Foundation.framework中的NSMutableDic,效果更高,关键更通用,不仅限于iOS.),实现了一个key和Node的哈希。

  3. 同时存储了如数量限制、总容量限制、存活时间限制,作为可配置参数存在。

3. Disk Cache

将文件存储和sqlite相结合
数据库结构
数据小于20K存于inline_data中,大于20k,存在文件中,filename字段存储元数据,即文件名,从而实现了最高效的存储。
核心数据存储代码

- (void)setObject:(id<NSCoding>)object forKey:(NSString *)key {    if (!key) return;    if (!object) {        [self removeObjectForKey:key];        return;    }    NSData *extendedData = [YYDiskCache getExtendedDataFromObject:object];    NSData *value = nil;    if (_customArchiveBlock) {        value = _customArchiveBlock(object);    } else {        @try {            value = [NSKeyedArchiver archivedDataWithRootObject:object];        }        @catch (NSException *exception) {            // nothing to do...        }    }    if (!value) return;    NSString *filename = nil;    if (_kv.type != YYKVStorageTypeSQLite) {        if (value.length > _inlineThreshold) {            filename = [self _filenameForKey:key];        }    }    Lock();    [_kv saveItemWithKey:key value:value filename:filename extendedData:extendedData];    Unlock();}

最后有个疑惑,读了一遍源码,在使用时是不是整个工程用一份YYCache(或者说是单例,因为内存缓存是存在YYCache的实例中的),那么这样会不会造成DishCache的customArchiveBlock有可能特别大呢

0 0