NSCache
NSCache
是苹果官方提供的缓存类,它的用法和NSMutableDictionary
非常类似.
NSCache
是一个类似于集合的容器,即缓存.它存储key-value,这一点非常类似 NSDictionary
. 开发者一般用 NSCache
来缓存临时存储短时间但是使用创建成本高的对象,重用这些对象可以优化性能,因为他们的值不需要被重新计算.另外一方面,这些对象对于程序来说是不要紧的,在内存紧张的时候会被丢弃,如果对象被丢弃了,则下次使用的时候需要重新计算.
当一个key-value
对在缓存时,缓存维护它的一个强引用.存储在NSCache
中的通用数据类型通常是实现了NSDiscardableContent
协议的对象.在缓存中存储这类对象的好处是,当你不需要它的时候可以丢弃这些内容,以节省内存.默认情况下,缓存中的NSDiscardableContent
对象在其内容被丢弃的时候,会被移除缓存,如果一个NSDiscardableContent
被放进缓存,则在对象被移除时,缓存会调用discardContentIfPossible
方法。
NSCache
与可变集合的不同:
1.NSCache
类结合了各种自动删除策略,以确保不会占用过多的系统内存。如果其它应用需要内存时,系统自动执行这些策略。当调用这些策略时,会从缓存中删除一些对象,以最大限度减少内存的占用
2.NSCache
是线程安全的,我们可以在不同的线程中添加、删除和查询缓存中的对象,而不需要锁定缓存区域。
3.不像NSMutableDictionary
对象,一个缓存对象不会拷贝key
对象。
Managing Cache Size (管理缓存大小)
@property NSUInteger countLimit
缓存应持有的对象的最大数量。
This is not a strict limit—if the cache goes over the limit, an object in the cache could be evicted instantly, later, or possibly never, depending on the implementation details of the cache.
这不是一个严格的限制。如果缓存的数量超过这个数量,缓存中的一个对象可能会被立即丢弃、或者稍后、也可能永远不会,具体依赖于缓存的实现细节。
@property NSUInteger totalCostLimit
来限定缓存能维持的最大内存,但totalCostLimit也不是一个严格限制
Managing Discardable Content(管理丢弃内容)
@property BOOL evictsObjectsWithDiscardedContent
是否自动清理缓存,默认是YES
Adding and Removing Cached Values(存取缓存的方法)
- setObject:forKey:
- setObject:forKey:cost:
- removeObjectForKey:
- removeAllObjects
NSCacheDelegate
- (void)cache:(NSCache *)cache
willEvictObject:(id)obj
缓存将要删除对象时调用,不能在此方法中修改缓存。
实践
- (NSCache *)cache
{
if (_cache == nil) {
_cache = [[NSCache alloc] init];
_cache.delegate = self;
}
return _cache;
}
self.cache.countLimit = 5;
for (int i = 0; i < 10; i++) {
NSString *str = [NSString stringWithFormat:@"我是第%d个",i];
[_cache setObject:str forKey:[NSString stringWithFormat:@"%d",i] ];
}
NSString *str = [_cache objectForKey:@"0"];
NSLog(@"str0:%@",str);
str = [_cache objectForKey:@"5"];
NSLog(@"str5:%@",str);
str = [_cache objectForKey:@"6"];
NSLog(@"str6:%@",str);
str = [_cache objectForKey:@"7"];
NSLog(@"str7:%@",str);
- (void)cache:(NSCache *)cache willEvictObject:(nonnull id)obj
{
NSLog(@"被删除的对象是:%@",obj);
}
从运行结果能看出,
_cache
只保存了最新的5个字符串,最先加入的5个字符串后来被删除掉了,但是文档也指出了countLimit并不是一个严格的限制,如果cache数量超出了limit,那么cache中的对象有可能立刻被清理出去,或者稍后,或者永远都不会被清理掉,而这个时机依赖于cache的实现细节