構建緩存時使用--NSCache而非NSDictionary的理由:1.當系統(tǒng)資源將要耗盡的時候则酝,NSCache可以自動刪減緩存,而且線性刪減"最久未使用的"對象拧晕,NSCache是不是很強大十酣。但是NSDictionary就需要在系統(tǒng)發(fā)出"低內(nèi)存"通知時手工刪減緩存,還需要自己編寫相應優(yōu)先刪減內(nèi)存等一系列邏輯蚊丐。
2.NSCache是線程安全的,可以在供多個線程同時訪問NSCache但是NSDictionary就不具備此優(yōu)勢
3.NSCache對象不拷貝鍵艳吠,因為很多時候鍵都是由不支持拷貝操作的對象來充當?shù)穆蟊福虼薔SCache不會自動拷貝
要點:1.將? NSPurgeableData與NSCache搭配使用,可實現(xiàn)自動清除數(shù)據(jù)的功能昭娩,當NSPurgeableData對象所占內(nèi)存為系統(tǒng)所丟棄時凛篙,該對象也會從緩存中移除
2.如果緩存使用的得當,會使應用程序的響應速度提高栏渺。只有那些重新計算起來很費事的數(shù)據(jù)呛梆,才值得放入緩存,如通過網(wǎng)絡獲取或從磁盤讀取的數(shù)據(jù)
#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是提前知道該緩存對象占用的字節(jié)數(shù)秀仲,也會考慮緩存的限制屬性融痛,推薦使用?
- (void)setObject:(ObjectType)obj forKey:(KeyType)key - (void)removeObjectForKey:(KeyType)key;?
?- (void)removeAllObjects; @property NSUInteger totalCostLimit; // limits are imprecise/not strict-設置緩存占用的內(nèi)存大小,并不是一個嚴格的限制神僵,當總數(shù)超過了totalCostLimit設定的值雁刷,系統(tǒng)會清除一部分緩存,直至總消耗低于totalCostLimit的值?
@property NSUInteger countLimit; // limits are imprecise/not strict----設置緩存對象的大小保礼,也不是一個嚴格的限制
?@property BOOL evictsObjectsWithDiscardedContent;//來標識緩存是否自動舍棄那些內(nèi)存已經(jīng)被丟棄的對象默認為YES,如果設置為YES沛励,則在對象的內(nèi)存被丟棄時舍棄對象。 @end?
@protocol NSCacheDelegate//實現(xiàn)了NSCacheDelegate代理的對象炮障,在緩存對象即將被清理的時候目派,系統(tǒng)回調(diào)代理方法如下:
@optional
- (void)cache:(NSCache *)cache willEvictObject:(id)obj;//第一個參數(shù)是當前緩存(NSCache),不要修改該對象胁赢;
第二個參數(shù)是當前將要被清理的對象企蹭,如果需要存儲該對象,可以在此操作(存入Sqlite or CoreData);該代理方法的調(diào)用會在緩存對象即將被清理的時候調(diào)用,如下場景會調(diào)用:
1. - (void)removeObjectForKey:(id)key; 手動刪除對象谅摄;
2. 緩存對象超過了NSCache的屬性限制徒河;(countLimit 和 totalCostLimit )
3. App進入后臺會調(diào)用;
4. 系統(tǒng)發(fā)出內(nèi)存警告送漠;
@end
NS_ASSUME_NONNULL_END
建議:需要使用緩存顽照,就使用系統(tǒng)的NSCache就行了
NSCache的使用:
NSData *data;
NSString *key;
NSCache *cache = [[NSCache alloc] init]; //創(chuàng)建
[cache setObject:data forKey:key]; //保存
[cache setObject:data forKey:key cost:50];//cost用于計算記錄在緩沖中所有對象的總成本。當出現(xiàn)內(nèi)存警告闽寡,或者超出緩存的成本上限時代兵,緩存會開啟一個回收過程,刪除部分元素爷狈。
cache.totalCostLimit = 100;//緩存空間的最大成本植影,超出上限會自動回收對象。默認值是0沒有限制
cache.countLimit = 100;//能夠緩存對象的最大數(shù)量淆院,默認值也是0(默認沒有限制)
cache.evictsObjectsWithDiscardedContent = YES;//標示是否回收廢棄的內(nèi)容何乎,默認值是YES(自動回收)
NSData *cacheData = [cache objectForKey:key]; //獲取
[cache removeObjectForKey:key];
[cache removeAllObjects];