iOS快取策略之NSCache的簡單使用
阿新 • • 發佈:2018-11-15
NSCache是一個繼承NSObjec的可變集合,是蘋果提供的一套快取機制,用鍵值(key-value)對來臨時儲存只需要短暫儲存在記憶體中的資料,並且當記憶體空間很少的時候會可以自動釋放一些資源。
概觀
快取(cache)物件和其他可變集合不同的幾個方面。
NSCache
類包含了各種自動銷燬策略,來保證快取內容沒有佔用過多的系統記憶體。如果其他應用需要記憶體,這些策略會從系統中移除一些選項內容,來減少當前app佔用的記憶體空間。- 可以在不同的執行緒中對記憶體中的快取執行新增、移除和查詢操作,而不必自己鎖住快取,因為是執行緒安全的。
- 不同於
NSMutableDictionary
NSCache
可以指定快取數量(限額)和一共可用的空間容量,當快取超出限額或者可用記憶體容量會自動釋放相應記憶體。
通常使用NSCache物件去臨時儲存那些建立很昂貴的過渡資料。重用這些資料可以提供效能優勢,因為這些值沒必要被重新計算。有些資料並非是關鍵資料,在記憶體緊張的時候,可以被丟棄。如果丟棄,這些值將會被重新計算。
具有子元件的物件在沒有被使用時可以被丟棄,該物件可以採用NSDiscardableContent協議,去提高快取回收行為。預設情況下。在快取中的NSDiscardableContent物件丟棄的內容會被自動移出快取,即使這個自動移除政策是可以修改的。如果一個NSDiscardableContent物件被放進快取中,那麼當該物件被移出時會呼叫discardContentIfPossible。
使用
以下可以使用,從多個方法介紹NSCache。
// 快取的名稱
@property (copy) NSString *name;
設定快取空間
// 物件快取可持有最大的數量 ,預設是0 沒有限制),一旦超出限額,會自動刪除之前新增的快取資料
@property NSUInteger countLimit;
// 快取中可持有的最大空間 預設是0(沒有限制)
@property NSUInteger totalCostLimit;
管理丟棄內容
// 是否可以自動快取清除可丟棄的內容,預設是YES @property BOOL evictsObjectsWithDiscardedContent; // 可以實現這個協議,當類的物件有可以被銷燬不再使用的子元件。這樣使用app佔用更少的記憶體空間。 NSDiscardableContent
設定代理
// cache的代理
@property (nullable, assign) id<NSCacheDelegate> delegate;
// 一個NSCache物件的代理,實現這些協議代理,去將物件從快取中移除
NSCacheDelegate
獲取一個快取值
// 返回給定key關聯的value值
- (nullable ObjectType)objectForKey:(KeyType)key;
新增和移除快取值
// 根據key值設定在快取中的value值
- (void)setObject:(ObjectType)obj forKey:(KeyType)key; // 0 cost
// 根據key值設定在快取中的value值,並且指定關聯key-value對的成本
- (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g;
// 根據key值移除在快取的value值
- (void)removeObjectForKey:(KeyType)key;
// 清空全部快取,呼叫次方法依然可以新增新值,網上很多很多複製貼上的部落格,都說呼叫次方法後不能新增,親測是可以的。
- (void)removeAllObjects;
NSCacheDelegate 方法
@protocol NSCacheDelegate <NSObject>
@optional
// 回收記憶體空間使用。
// cache 快取物件。
// obj 被回收的物件。
- (void)cache:(NSCache *)cache willEvictObject:(id)obj;
@end
在NSObject.h中的可以廢棄內容。
/*********** Discardable Content ***********/
@protocol NSDiscardableContent
@required
- (BOOL)beginContentAccess;
- (void)endContentAccess;
- (void)discardContentIfPossible;
- (BOOL)isContentDiscarded;
@end
@interface NSObject (NSDiscardableContentProxy)
@property (readonly, retain) id autoContentAccessingProxy;
@end
使用
- 初始化物件
// 1. 初始化資料
- (NSCache *)mainCache{
if (!_mainCache) {
_mainCache = [[NSCache alloc] init];
_mainCache.countLimit = 300; // 限制個數,預設是0,無限空間
_mainCache.totalCostLimit = 5*1024*1024; // 設定大小設定,預設是0,無限空間
_mainCache.name = @"cache1";
_mainCache.delegate = self;
}
return _mainCache;
}
- 新增快取
// 新增快取
[self.mainCache setObject:data forKey:str];
- 移除。在記憶體警告的時候(
didReceiveMemoryWarning
)移除快取。給物件傳送removeAllObjects
,後新增快取setObject:forKey:
是可以的,可以再新增進去的。還有一個根據key移除對應的值。
[self.mainCache removeAllObjects];
//[self.mainCache removeObjectForKey:@"XXX"];
- 代理
在當前物件遵守NSCacheDelegate協議。並且實現協議。並且讓當前物件成為代理_mainCache.delegate = self;
- (void)cache:(NSCache *)cache willEvictObject:(id)obj{
NSLog(@"%s",__func__);
}