iOS緩存策略之NSCache的簡單使用

NSCache是一個繼承NSObjec的可變集合,是蘋果提供的一套緩存機制,用鍵值(key-value)對來臨時存儲只需要短暫存儲在內存中的數據,並且當內存空間很少的時候會可以自動釋放一些資源。

概觀

緩存(cache)對象和其他可變集合不同的幾個方面。

  • NSCache類包含了各種自動銷燬策略,來保證緩存內容沒有佔用過多的系統內存。如果其他應用需要內存,這些策略會從系統中移除一些選項內容,來減少當前app佔用的內存空間。
  • 可以在不同的線程中對內存中的緩存執行添加、移除和查詢操作,而不必自己鎖住緩存,因爲是線程安全的。
  • 不同於NSMutableDictionary對象,緩存使用的key是不需要是實現NSCopying協議的,NSMutableDictionary是非線程安全的,在OC中可變類型一般都是非線程安全的。
  • 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. 初始化對象
// 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;
}
  1. 添加緩存
// 添加緩存
 [self.mainCache setObject:data forKey:str];
  1. 移除。在內存警告的時候(didReceiveMemoryWarning)移除緩存。給對象發送removeAllObjects,後添加緩存setObject:forKey:是可以的,可以再添加進去的。還有一個根據key移除對應的值。
[self.mainCache removeAllObjects];
//[self.mainCache removeObjectForKey:@"XXX"];
  1. 代理
    在當前對象遵守NSCacheDelegate協議。並且實現協議。並且讓當前對象成爲代理_mainCache.delegate = self;
- (void)cache:(NSCache *)cache willEvictObject:(id)obj{
    NSLog(@"%s",__func__);
}

推薦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章