什么是NSCache缓存
NSCache主要用来存储临时数据(键值对),当内存资源不够时,系统会自动释放部分数据。它有三个特色:
• NSCache为了保持不占用过多的系统内存,它有多种自动回收内存策略;当系统内存出现不足时,它会回收部份内存使系统正常运转,这种回收是不可控的。
• 能够在多线程中对NSCache进行访问,同时不须要加锁,由于它是线程安全的。
• 与NSMutableDictionary不一样,NSCache不会copy其内部的键对象。
由上边的特色看出,NSCache是一个很好的内存缓存类,经过它咱们能够实现数据的缓存功能。常见的开源框架中也有NSCache的使用,AFN的图片缓存,SDWebImage等。安全
NSCache测试多线程
下面验证NSCache的特性,包含三个部分。NSCache的缓存能力有多大?多线程访问下是否安全?是否会copy其内部对象?框架
1. 缓存能力
NSCache提供了totalCostLimit和countLimit属性让外界可以对其进行缓存大小和缓存数量进行限制,可是不精确。网上其余的帖子说到大约NSCache的缓存能力是500M,如今咱们对其验证。
NSCache *cache = [[NSCache alloc] init];
int a = 0;
while (YES) {
NSString *string = @"一长串字符串"; // 大约1000个左右字符
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
NSString *key = [NSString stringWithFormat:@"%d", a];
[cache setObject:data forKey:key];
a++;
}
经过上述的代码运行在iPhone6上,内存升到600M多点直接崩溃,那么极限是500多应该是正确的。同时在快速达到内存极限时,系统是来不及释放回收的,使用时应当注意,并且上边的代码是死循环,速度很是快。
2. 多线程访问
多线程访问单独读取是不会形成问题的,除非访问线程数过多,这里咱们模拟多线程同时写入的状况。
NSCache *cache = [[NSCache alloc] init];
NSString *string = @"一长串字符串"; // 大约1000个左右字符
for (int i = 0; i < 10; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[cache setObject:[NSString stringWithFormat:@"%d%@",i,string] forKey:@"MulPth"];
NSLog(@"object is %@", [cache objectForKey:@"MulPth"]);
});
}async
string若设置为特别短的字符串,效果可能不是很明显,因此将缓存能力中的字符串拷贝过来测试,从打印结果看,时间戳有明显差别,同时顺序也不是0123456789,而其他的内容一致,能够得出是线程安全的。
本质上,NSCache在其内部使用了pthread_mutex互斥锁进行线程安全保护。测试