介绍 NSCache 一个存储键-值对的容器,和NSDictionary 很像,它可以设置存储键-值对的最大数量 优点 1.NSCache 包含了回收策略,确保了NSCache 不会使用太多系统的内存 nil nil Optional(6) Optional(7) Optional(8) Optional(9) Optional(10) 设置缓存消耗最大数量 let cache = NSCache func isContentDiscarded() -> Bool{ print("执行了isContentDiscarded") return isDiscard } } 第二步 使用NSCache 代理事件 optional public func cache(_ cache: NSCache<AnyObject, AnyObject>, willEvictObject obj: Any) 提示: 设置代理之后,一旦NSCache 缓存的对象被丢弃,会触发这个时间
你要知道的NSCache都在这里 转载请注明出处 https://cloud.tencent.com/developer/user/1605429 本篇文章首先会详细讲解NSCache的基本使用,NSCache NSCache NSCache的使用很方便,提供了类似可变字典的使用方式,但它比可变字典更适用于实现缓存,最重要的原因为NSCache是线程安全的,使用NSMutableDictionary自定义实现缓存时需要考虑加锁和释放锁 ,NSCache已经帮我们做好了这一步。 上面讲解的三点就是NSCache相比于NSMutableDictionary实现缓存功能的优点,在需要实现缓存时应当优先考虑使用NSCache。 上面就是NSCache的基本用法了,我们只需要设置对象和获取对象,其他事情NSCache都帮我们做完了,因此,实现缓存功能时,使用NSCache就是我们的不二之选。
NSCache NSCache是一个非常奇怪的集合。在iOS 4/Snow Leopard中加入,默认为可变并且线程安全的。这使它很适合缓存那些创建起来代价高昂的对象。 NSCache性能 那么NSCache如何承受NSMutableDictionary的考验?加入的线程安全必然会带来一些消耗。 4. iOS 构建缓存时选 NSCache 而非NSDictionary 当系统资源将要耗尽时,NSCache可以自动删减缓存。 如果采用普通的字典,那么就要自己编写挂钩,在系统通知时手动删减缓存,NSCache会先行删减 时间最久为被使用的对象 NSCache 并不会拷贝键,而是会保留它。 因此NSCache对象不会自动拷贝键,所以在键不支持拷贝操作的情况下,该类比字典用起来更方便 NScache是线程安全的,NSDictionary不是。
NSCache NSCache是苹果官方提供的缓存类,用法与NSMutableDictionary的用法很相似,在AFNetworking和SDWebImage中,使用它来管理缓存 当系统资源将要耗尽时 ,它可以自动删除缓存(NSCache会先行删减“最久未使用的”对象,) NSCache并不会拷贝key,而是会保留它,因为大多数key值都是由不支持拷贝的对象来充当的 NScache是线程安全的,在多线程操作中 ,不需要对Cache加锁 NSCache的属性 countLimit:能够缓存对象的最大数量,默认值是0(没有限制) totalCostLimit :缓存空间的最大成本,超出上限会自动回收对象。 默认值是0(没有限制) 当超出缓存最大成本或数量时,NSCache会把前面的数据即最开始存的给清除掉 evictsObjectsWithDiscardedContent:表示是否回收废弃的内容,默认值是 YES(自动回收) NSCache的方法 objectForKey:返回与键值关联的对象 setObject: forKey: 在缓存中设置指定键名对应的值。
深入源码理解YYCache 、SDWebImage、AFNetworking、NSCache 缓存方式与对比 转载请注明出处 https://cloud.tencent.com/developer/user /1605429 在之前的一篇文章iOS缓存 NSCache详解及SDWebImage缓存策略源码分析中详细讲解了NSCache的用法以及SDWebImage内存和磁盘缓存的源码分析,本篇文章将简要讲解 由于之前的一篇文章已经详细讲解了NSCache和SDWebImage缓存策略,本篇文章不再赘述,会简要介绍一下AFNetworking和YYCache的源码。 基于内存的缓存可以使用NSCache和NSMutableDictionary来实现,但使用NSCache其清除缓存的算法不是我们可控的,比如我们想要LRU淘汰算法,或者FILO、FIFO等各种算法都没办法实现 ,此时只能自己实现,并且NSCache缓存的读写效率并不高,他帮我们做的只有自动清理缓存,所以在性能要求不高的情况下使用NSCache很合适,其实现简单,已经帮我们完成了所有的工作,我们只需要像操作字典一样操作他
在 SDWebImage 中,设计了两种缓存 1.SDMemoryCache:它继承自 NSCache 用来实现内存缓存 2.NSFileManager:使用文件的方式来实现磁盘缓存 先来看一下 SDImageCache ,也会对图片进行内存缓存,并且它还是线程安全的 问题:既然NSCache已经可以实现图片的内存缓存了,为啥还要加一个NSMapTable来再缓存一次呢? ,所以作者在NSCache的基础上又加了一个NSMapTable缓存,这应该是为了提高内存缓存的命中率吧 NSCache的相关内容可以参考这篇文章 http://nshipster.cn/nscache / 我们再来看一下具体的代码实现,作者重写了NSCache的方法来实现了NSMapTable的缓存,为了方便阅读,我删除了线程安全的代码 - (void)setObject:(id)obj forKey :(id)key cost:(NSUInteger)g { // 先将对象缓存的 NSCache 中 [super setObject:obj forKey:key cost:g];
NSCache 初始化时报错,提示不能推断 var cache = NSCache() 修改: var cache = NSCache<AnyObject, AnyObject>() clang:
nonatomic) NSUInteger maxMemoryCountLimit; 设置最大内存消耗和最多数量的限制 2、清理Memory缓存 @interface AutoPurgeCache : NSCache 判断当前图片类型:只判断图片二进制数据的第一个字节 默认的缓存周期:1周 缓存策略:默认情况下既做内存缓存又做磁盘缓存,下载图片前先检查内存缓存,再检查磁盘缓存 缓存的实现方式:采用了苹果推出的专门用来处理缓存的类NSCache
第50条:构建缓存时选用NSCache 而非NSDictionary 如果我们缓存使用得当,那么应用程序的响应速度就会提高。 NSCache优于NSDictionary的几点: 当系统资源将要耗尽时,NSCache具备自动删减缓冲的功能。并且还会先删减“最久未使用”的对象。 NSCache不拷贝键,而是保留键。 NSCache是线程安全的:不编写加锁代码的前提下,多个线程可以同时访问NSCache。 关于操控NSCache删减内容的时机 开发者可以通过两个尺度来调整这个时机: 缓存中的对象总数. *_cache; } - (id)init { if ((self = [super init])) { _cache = [NSCache new]; // Cache NSPurgeableData NSPurgeableData是NSMutableData的子类,把它和NSCache配合使用效果很好。
第50条:构建缓存时选用NSCache 而非NSDictionary 如果我们缓存使用得当,那么应用程序的响应速度就会提高。 NSCache优于NSDictionary的几点: 当系统资源将要耗尽时,NSCache具备自动删减缓冲的功能。并且还会先删减“最久未使用”的对象。 NSCache不拷贝键,而是保留键。 NSCache是线程安全的:不编写加锁代码的前提下,多个线程可以同时访问NSCache。 关于操控NSCache删减内容的时机 开发者可以通过两个尺度来调整这个时机: 缓存中的对象总数. *_cache; } - (id)init { if ((self = [super init])) { _cache = [NSCache new]; // Cache NSPurgeableData NSPurgeableData是NSMutableData的子类,把它和NSCache配合使用效果很好。
将零碎的内容作为一个整体进行写入 使用合适的 I/O 操作 API 使用合适的线程 使用 NSCache 做缓存能够减少 I/O NSCache ? 达到如图的目的为何不直接用字典来做呢? NSCache 具有字典的所有功能,同时还有如下的特性: 自动清理系统占用内存 NSCache 是线程安全 -(void)cache:(NSCache *)cache willEvictObject:( id)obj; 缓存对象将被清理时的回调 evictsObjectsWithDiscardedContent 可以控制是否清理 那么 NSCache是如何做到这些特性的呢? 接下来学习下 NSCache 是如何做的。首先 NSCache 是会持有一个 NSMutableDictionary。 @implementation NSCache - (id) init { if (nil == (self = [super init])) { return nil;
interface DownloadImage() @property (nonatomic,strong)NSOperationQueue *queue; @property (nonatomic,strong)NSCache NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; } return _cachePath; } - (NSCache _imageCache) { _imageCache = [[NSCache alloc] init]; _imageCache.countLimit = 100;
1、内存缓存及磁盘缓存 1.内存缓存的处理由NSCache对象实现,NSCache类似一个集合的容器,它存储key-value对,类似于nsdictionary类,我们通常使用缓存来临时存储短时间使用但创建昂贵的对象 对于图片的索引,我们通过一个key来索引,在内存中,我们将其作为NSCache的key值,而在磁盘中,我们用这个key值作为图片的文件名,对于一个远程下载的图片其url实作为这个key的最佳选择。 操作队列的优点是可以取消在任务处理队列中的任务,另外在管理操作间的依赖关系方面容易一些,对SDWebImage中我们看到如何使用依赖将下载顺序设置成后进先出的顺序 4.NSURLSession:用于网络请求及相应处理 5.开启后台任务 6.NSCache
AnimationImageCache类是一个动画图片加载类,用单例实现且内部用NSCache持有引用。 注意,当收到内存不足警告时,NSCache会自动释放内存。 所以每次访问NSCache,即使上一次已经加载过,也需要判断返回值是否为空。 3、图片裁剪 为了减少图片资源的大小,有时候会把多个帧动画做成连续的一张图。
NSCache和NSURLCache名字相近,其实没有什么关系;NSCache可以认为是一个字典缓存,在内存不足的时候会自动释放对象。
private var _image: ImageModel private let cachedImages = NSCache<NSURL, UIImage>() init 所以,针对这个问题,我为我的应用加入了缓存 NSCache 对象,来对图片做一个缓存,具体代码实现如下: class ImageCache: NSObject { private var cache = NSCache<AnyObject, UIImage>() public static let shared = ImageCache() private override init () {} func getCache() -> NSCache<AnyObject, UIImage> { return cache } } 在下载开始的时候,
内存缓存 这里我们使用的内存缓存是系统提供的NSCache类。 NSCache基本使用方法与字典相同,以key值存值和取值。不同的是,NSCache会在内存吃紧的时候自动释放内存。 且相对于字典来说,NSCache是线程安全的,所以你并不需要手动加锁哦。 所以确定了内存缓存的实现方式后,我们只要部署缓存逻辑即可。 end #pragma mark --- DWWebImageCache --- @interface DWWebImageCache () @property (nonatomic ,strong) NSCache mark --- 接口方法 --- -(instancetype)init { self = [super init]; if (self) { _memCache = [[NSCache
可以使用NSCache,步骤如下: 1、加载cache中的图片; 如果有则返回,没有到步骤2; 2、加载本地的缓存文件,如果有则返回,没有到步骤3; 3、从网络下载图片,到步骤4; 4、存入本地的缓存文件 ,到步骤5; 5、放入cache,返回图片; 如果不需要网络下载图片,可以去除3、4步骤,同时可以同步返回; 如果使用array存储图片,会一直持有引用;NSCache会在内存不足时主动释放,故而加载的时候需先判断是否有缓存文件
completeBlock){completeBlock(image,error,imageURL);}}];returnYES;//表示已处理}@end7.2.1缓存系统设计(双重缓存策略)1、内存缓存通过NSCache 并使用异步的IO操作,避免阻塞接口接口定义,具体实现可以查看仓库展开代码语言:Objective-CAI代码解释/***KRImageCache-图片缓存管理器**功能特性:*-双重缓存策略:内存缓存(NSCache paramurl图片URL*@return生成的缓存键值(SHA256哈希)*/+(NSString*)cacheKeyForURL:(NSURL*)url;@property(nonatomic,strong)NSCache
NSDictionary 来管理帧缓存, iOS 系统在内存紧张时会对 NSDictionary 做压缩, 从而产生额外的 CPU 消耗, 根据 WWDC iOS Memory Deep Dive[1]所述, 应尽量使用 NSCache YYAnimatedImageView 会丢弃前一张图的所有帧数据, 下次展示这张图又会从头解码, 造成额外的 CPU 消耗, 在此继续做如下优化. 4.3.1 NSDictionary 帧缓存改为 NSCache 而 NSCache 更适合用于缓存开销较大的数据, 并且是线程安全的, 系统会自动根据内存使用情况以及cost 直接移除缓存, 在此次优化中, 解码帧使用 NSCache 来缓存. 4.3.2 解绑 使用 NSCache 代替 NSDictionary 做帧缓存, 避免系统压缩内存时带来额外 CPU 消耗, 并由系统自动释放帧缓存.