写高质量OC代码52建议总结:50.构建缓存时选用NSCache而非NSDictionary
来源:互联网 发布:microsoft相机软件 编辑:程序博客网 时间:2024/05/20 21:22
NSCache胜过NSDictionary之处在于,当系统资源耗尽时,他可以自动删减缓存,用字典就得自己写挂钩,系统低内存时手工删减,十分复杂。
NSCache不会“拷贝”键而是“保留”,这个点字典也能实现但是很复杂(49条~)。很多时候键都是由不支持拷贝的对象充当的,这点用起来比字典方便。NSCache是线程安全的,多个线程可以同时访问NSCache。
可以控制缓存删减的实际,有两个参数可以调整,一个是缓存中的对象总数,第二个是所有对象的总开销。
还有一个类是NSPurgeableData,和NSCache搭配使用,此类事NSMutableData的子类,实现了NSDiscardableContent协议。当系统资源紧张时可以把保存的NSPurgeableData对象的那块内存释放掉。NSDiscardableContent协议定义了isContentDiscarded的方法,查询相关内存是否已被释放。
如果需要访问某个NSPurgeableData对象,可以调用beginContentAsscee方法,告诉它现在还不应该丢弃自己所占的内存。用完后调用endContentAccess方法,告诉它在必要的时候可以丢弃自己所占的内存。
将NSPurgeableData对象加入NSCache,当该对象被丢弃时,也会自动从系统中移除,通过NSCache的evictsObjectsWithDiscardedContent属性,可以开关此功能。
上面的例子可用NSPurgeableData改写:
总结:
1.NSCache可以提供自动删减缓存功能,而且保证线程安全,与字典不同,不会拷贝键。
2.NSCache可以设置缓存上限,限制对象个数和总缓存开销。定义了删除缓存对象的时机。这个机制只对NSCache起到指导作用,不会一定执行。
3.NSPurgeableData搭配NSCache使用,可以自动清除数据。
4.只有那种“重新计算很费劲”的数据才值得放入缓存。
NSCache不会“拷贝”键而是“保留”,这个点字典也能实现但是很复杂(49条~)。很多时候键都是由不支持拷贝的对象充当的,这点用起来比字典方便。NSCache是线程安全的,多个线程可以同时访问NSCache。
可以控制缓存删减的实际,有两个参数可以调整,一个是缓存中的对象总数,第二个是所有对象的总开销。
向缓存中加入的对象必须可以很快的计算出开销值。如果计算过程复杂会大大浪费资源,违背缓存的设计初衷。如果加入缓存的对象是NSData,直接可以将数据大小作为开销值,不需要计算,已经是NSData的一个属性了。
#import "fiftyDemo.h"typedef void(^EOCNetworkFercherCompletionHandler)(NSData *data);@interface EOCNetworkFetcher : NSObject-(id)initWithURL:(NSURL *)url;-(void)startWithCompletionHandler:(EOCNetworkFercherCompletionHandler)handler;@end@implementation fiftyDemo { NSCache *_cache;}-(id)init { self = [super init]; if (self) { _cache = [NSCache new]; _cache.countLimit = 100; // 最大对象数100 _cache.totalCostLimit = 5 * 1024 * 1024; // 总开销5MB }; return self;}-(void)downloadDataForURL:(NSURL *)url { NSData *cachedData = [_cache objectForKey:url]; if (cachedData) { //[self useData:cachedData]; } else { EOCNetworkFetcher *fetcher = [[EOCNetworkFetcher alloc] initWithURL:url]; [fetcher startWithCompletionHandler:^(NSData *data) { [_cache setObject:data forKey:url cost:data.length]; //[self useData]; }]; }}@end在本例中,可缓存对象总数设置为100,总开销上限设置为5MB。
还有一个类是NSPurgeableData,和NSCache搭配使用,此类事NSMutableData的子类,实现了NSDiscardableContent协议。当系统资源紧张时可以把保存的NSPurgeableData对象的那块内存释放掉。NSDiscardableContent协议定义了isContentDiscarded的方法,查询相关内存是否已被释放。
如果需要访问某个NSPurgeableData对象,可以调用beginContentAsscee方法,告诉它现在还不应该丢弃自己所占的内存。用完后调用endContentAccess方法,告诉它在必要的时候可以丢弃自己所占的内存。
将NSPurgeableData对象加入NSCache,当该对象被丢弃时,也会自动从系统中移除,通过NSCache的evictsObjectsWithDiscardedContent属性,可以开关此功能。
上面的例子可用NSPurgeableData改写:
-(void)downloadDataForURLTwo:(NSURL *)url { NSPurgeableData *cachedData = [_cache objectForKey:url]; if (cachedData) { [cachedData beginContentAccess]; // [self useData:cacheData]; [cachedData endContentAccess]; } else { EOCNetworkFetcher *fetcher = [[EOCNetworkFetcher alloc] initWithURL:url]; [fetcher startWithCompletionHandler:^(NSData *data) { NSPurgeableData *purgeableData = [NSPurgeableData dataWithData:data]; [_cache setObject:purgeableData forKey:url cost:purgeableData.length]; //[self useData:purgeableData]; [purgeableData endContentAccess]; }]; }}注意:创建好NSPurgeableData后,其purge计数会多1,不用先执行beginContentAsscee方法,使用完后需要执行endContentAccess方法。
总结:
1.NSCache可以提供自动删减缓存功能,而且保证线程安全,与字典不同,不会拷贝键。
2.NSCache可以设置缓存上限,限制对象个数和总缓存开销。定义了删除缓存对象的时机。这个机制只对NSCache起到指导作用,不会一定执行。
3.NSPurgeableData搭配NSCache使用,可以自动清除数据。
4.只有那种“重新计算很费劲”的数据才值得放入缓存。
阅读全文
0 0
- 写高质量OC代码52建议总结:50.构建缓存时选用NSCache而非NSDictionary
- 构建缓存时选用NSCache而非NSDictionary
- 编写高质量OC代码52建议总结:19.使用清晰而协调的命名方式
- 写高质量OC代码52建议总结:39.用handler块降低代码分散程度
- 写高质量OC代码52建议总结:32.编写“异常安全代码”时留意内存管理问题
- 写高质量OC代码52建议总结:28.通过协议提供匿名对象
- 写高质量OC代码52建议总结:30.以ARC简化引用计数
- 写高质量OC代码52建议总结:33.以弱引用避免保留环
- 写高质量OC代码52建议总结:35.用僵尸对象调试内存管理问题
- 写高质量OC代码52建议总结:36.不要使用retainCount
- 写高质量OC代码52建议总结:37.理解“块”
- 写高质量OC代码52建议总结:38.为常用的块创建typedef
- 写高质量OC代码52建议总结:41.多用派发列队,少用同步锁
- 写高质量OC代码52建议总结:42.多用GCD,少用performSelector系列方法
- 写高质量OC代码52建议总结:46.不要使用dispatch_get_current_queue
- 写高质量OC代码52建议总结:47.熟悉系统架构
- 写高质量OC代码52建议总结:48.多用块枚举,少用for循环
- 写高质量OC代码52建议总结:51.load和initialize
- 认证机构信息管理软件最重要的功能
- 使用userAgent区分浏览器版本
- 3、Eclipse+Maven创建web项目
- ubuntu java8
- Linux常用命令
- 写高质量OC代码52建议总结:50.构建缓存时选用NSCache而非NSDictionary
- ViewPager的setOnPageChangeListener方法详解
- 给循环一个标识符,break 的时候,直接跳出循环。
- Java程序与串口的通信实现及调试
- 实现60fps的网易云音乐首页
- RxJava 处理请求嵌套-- flatMap、Map
- quarte时间配置
- Gutrhie Arcv2CAD v7.0 A.19, CAD2Shape v7.0 A.27, dwgConvert v8.0 A.17\
- windows系统中,在地址栏输入\\,什么意思?