iOS---构建缓存时选用NSCache而非NSDiction
构建缓存时使用--NSCache而非NSDictionary的理由:1.当系统资源将要耗尽的时候,NSCache可以自动删减缓存,而且线性删减"最久未使用的"对象,NSCache是不是很强大。但是NSDictionary就需要在系统发出"低内存"通知时手工删减缓存,还需要自己编写相应优先删减内存等一系列逻辑。
2.NSCache是线程安全的,可以在供多个线程同时访问NSCache但是NSDictionary就不具备此优势
3.NSCache对象不拷贝键,因为很多时候键都是由不支持拷贝操作的对象来充当的,因此NSCache不会自动拷贝
要点:1.将 NSPurgeableData与NSCache搭配使用,可实现自动清除数据的功能,当NSPurgeableData对象所占内存为系统所丢弃时,该对象也会从缓存中移除
2.如果缓存使用的得当,会使应用程序的响应速度提高。只有那些重新计算起来很费事的数据,才值得放入缓存,如通过网络获取或从磁盘读取的数据
#import<Foundation/NSObject.h>
@class NSString;
@protocol NSCacheDelegate;
NS_ASSUME_NONNULL_BEGIN NS_CLASS_AVAILABLE(10_6, 4_0)
@interface NSCache: NSObject
{
@private id _delegate;
void *_private[5];
void *_reserved;
}
@property (copy) NSString *name;
@property (nullable, assign) iddelegate;
- (nullable ObjectType)objectForKey:(KeyType)key;//获取缓存对象,基于键值对
- (void)setObject:(ObjectType)obj forKey:(KeyType)key; // 0 cost---存储缓存对象,考虑缓存的限制属性
- (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g;//-存储缓存对象,cost是提前知道该缓存对象占用的字节数,也会考虑缓存的限制属性,推荐使用
- (void)setObject:(ObjectType)obj forKey:(KeyType)key - (void)removeObjectForKey:(KeyType)key;
- (void)removeAllObjects; @property NSUInteger totalCostLimit; // limits are imprecise/not strict-设置缓存占用的内存大小,并不是一个严格的限制,当总数超过了totalCostLimit设定的值,系统会清除一部分缓存,直至总消耗低于totalCostLimit的值
@property NSUInteger countLimit; // limits are imprecise/not strict----设置缓存对象的大小,也不是一个严格的限制
@property BOOL evictsObjectsWithDiscardedContent;//来标识缓存是否自动舍弃那些内存已经被丢弃的对象默认为YES,如果设置为YES,则在对象的内存被丢弃时舍弃对象。 @end
@protocol NSCacheDelegate//实现了NSCacheDelegate代理的对象,在缓存对象即将被清理的时候,系统回调代理方法如下:
@optional
- (void)cache:(NSCache *)cache willEvictObject:(id)obj;//第一个参数是当前缓存(NSCache),不要修改该对象;
第二个参数是当前将要被清理的对象,如果需要存储该对象,可以在此操作(存入Sqlite or CoreData);该代理方法的调用会在缓存对象即将被清理的时候调用,如下场景会调用:
1. - (void)removeObjectForKey:(id)key; 手动删除对象;
2. 缓存对象超过了NSCache的属性限制;(countLimit 和 totalCostLimit )
3. App进入后台会调用;
4. 系统发出内存警告;
@end
NS_ASSUME_NONNULL_END
建议:需要使用缓存,就使用系统的NSCache就行了
NSCache的使用:
NSData *data;
NSString *key;
NSCache *cache = [[NSCache alloc] init]; //创建
[cache setObject:data forKey:key]; //保存
[cache setObject:data forKey:key cost:50];//cost用于计算记录在缓冲中所有对象的总成本。当出现内存警告,或者超出缓存的成本上限时,缓存会开启一个回收过程,删除部分元素。
cache.totalCostLimit = 100;//缓存空间的最大成本,超出上限会自动回收对象。默认值是0没有限制
cache.countLimit = 100;//能够缓存对象的最大数量,默认值也是0(默认没有限制)
cache.evictsObjectsWithDiscardedContent = YES;//标示是否回收废弃的内容,默认值是YES(自动回收)
NSData *cacheData = [cache objectForKey:key]; //获取
[cache removeObjectForKey:key];
[cache removeAllObjects];