OC缓存 NSCache介绍
2016-05-24 10:02
288 查看
NSCache是苹果官方提供的缓存类,它的用法与NSMutableDictionary的用法很相似,在AFNetworking中,使用它来作为图片缓存。
NSCache在系统发出低内存通知时,会自动删减缓存。在以下代码中,不断给NSCache中填充NSData,当大小在500M左右时,系统抛出 Received memory warning. 通知,之后从Cache中获取数据,发现Cache为空。
测试低内存通知时Cache清除
执行结果
NSCache可以设置数量限制,通过countLimit与 totalCostLimit来限制cache的数量或者限制cost。当缓存的数量超过countLimit,或者cost之和超过totalCostLimit,NSCache会自动释放部分缓存。例子如下:
测试countLimit
执行结果
可以看到,Cache中只保留了最新的30条记录。
在第二个例子中,Cache严格的按照LRU规则,清理了超出限制的旧数据。但是在文档中说明,countLimit并不是一个严格的限制,如果cache数量超出了limit,那么cache中的对象有可能立刻被清理出去,或者稍后,或者永远都不会被清理掉,而这个时机依赖于cache的实现细节。
在使用setObject:forKey:cost:方法时,cost值只在比较容易获取到的时候才指定,若要通过复杂的计算来获取cost值,那使用缓存的意义就不大了。
NSCache是线程安全的,在多线程操作中,不需要对Cache加锁。NSCache的Key只是对对象的strong引用,对象不需要实现NSCopying协议,NSCache也不会像NSDictionary一样复制对象。
通常,使用NSCache会结合NSDiscardableContent协议,实现了这个协议的类需要在被引用之前,必须调用beginContentAccess来标记为可使用的,如果在使用之前没有调用beiginContentAccess,那么就会抛出异常。在使用结束之后,调用endContentAccess,来标记它为可以被释放的。如果实现了NSDiscardableContent协议的对象放入了NSCache中,那么,在清除它的时候,会调用discardContentIfPossible方法来判断引用状况,没有引用,则销毁。
在AFNetworking的UIKit中,使用了NSCache来提供异步图片下载的缓存。UIImageView+AFNetworking.h文件中,声明了一个AFImageCache协议,提供读取和放入缓存的方法。UIImageView+AFNetworking.m文件中,声明了一个继承自NSCache的类AFImageCache,实现了AFImageCache协议,并且实现了协议中的两种文件操作方法,实现代码如下:
AFNetworking中的实现
使用absolute URL作为key,将图片缓存起来。在UIImageView类中,通过单例方式,获取AFImageCache的实例。代码如下:
获取AFImageCache单例
若在其他地方下载了图片,只需调用sharedImageCache方法,获取到一个NSCache实例,将图片放入缓存,URL作为key,那么再调用UIImageView时,指定URL,就可以直接从缓存中获取图片。
官方指导:NSCache
NSCache在系统发出低内存通知时,会自动删减缓存。在以下代码中,不断给NSCache中填充NSData,当大小在500M左右时,系统抛出 Received memory warning. 通知,之后从Cache中获取数据,发现Cache为空。
测试低内存通知时Cache清除
执行结果
NSCache可以设置数量限制,通过countLimit与 totalCostLimit来限制cache的数量或者限制cost。当缓存的数量超过countLimit,或者cost之和超过totalCostLimit,NSCache会自动释放部分缓存。例子如下:
测试countLimit
执行结果
可以看到,Cache中只保留了最新的30条记录。
在第二个例子中,Cache严格的按照LRU规则,清理了超出限制的旧数据。但是在文档中说明,countLimit并不是一个严格的限制,如果cache数量超出了limit,那么cache中的对象有可能立刻被清理出去,或者稍后,或者永远都不会被清理掉,而这个时机依赖于cache的实现细节。
在使用setObject:forKey:cost:方法时,cost值只在比较容易获取到的时候才指定,若要通过复杂的计算来获取cost值,那使用缓存的意义就不大了。
NSCache是线程安全的,在多线程操作中,不需要对Cache加锁。NSCache的Key只是对对象的strong引用,对象不需要实现NSCopying协议,NSCache也不会像NSDictionary一样复制对象。
通常,使用NSCache会结合NSDiscardableContent协议,实现了这个协议的类需要在被引用之前,必须调用beginContentAccess来标记为可使用的,如果在使用之前没有调用beiginContentAccess,那么就会抛出异常。在使用结束之后,调用endContentAccess,来标记它为可以被释放的。如果实现了NSDiscardableContent协议的对象放入了NSCache中,那么,在清除它的时候,会调用discardContentIfPossible方法来判断引用状况,没有引用,则销毁。
在AFNetworking的UIKit中,使用了NSCache来提供异步图片下载的缓存。UIImageView+AFNetworking.h文件中,声明了一个AFImageCache协议,提供读取和放入缓存的方法。UIImageView+AFNetworking.m文件中,声明了一个继承自NSCache的类AFImageCache,实现了AFImageCache协议,并且实现了协议中的两种文件操作方法,实现代码如下:
AFNetworking中的实现
使用absolute URL作为key,将图片缓存起来。在UIImageView类中,通过单例方式,获取AFImageCache的实例。代码如下:
获取AFImageCache单例
若在其他地方下载了图片,只需调用sharedImageCache方法,获取到一个NSCache实例,将图片放入缓存,URL作为key,那么再调用UIImageView时,指定URL,就可以直接从缓存中获取图片。
官方指导:NSCache
相关文章推荐
- 自定义缓存配置(非Web项目)
- PHPcms栏目页调取多图字段的方法
- 由浅入深探究 MySQL索引结构原理、性能分析与优化(一)
- js数组操作大全(pop,push,unshift,splice,shift方法)
- exec-timeout,session-timeout,timeout
- Ogre: 天空
- swift基础笔记2-闭包
- Android EventBus实战 没听过你就out了
- 使用MyBatis对表执行CRUD操作
- 【Spring4揭秘 基础1】监听器和事件
- HDU 5699 货物运输 二分
- .replace(R.id.container, new User()).commit();/The method replace(int, Fragment) in the type FragmentTransaction is not app
- .replace(R.id.container, new User()).commit();/The method replace(int, Fragment) in the type FragmentTransaction is not app
- 如何从乱码中恢复 (下)?
- android-关于圆形头像
- 修改django.admin中一个应用的名称
- 注册界面设计
- iOS中的加号和减号方法
- DNS原理及其解析过程【精彩剖析】
- 冒泡排序