NSCache的簡單介紹應用

NSCache

介紹
NSCache 是蘋果提供的一個專門用來做緩存的類
使用和 NSMutableDictionary 非常相似
是線程安全的
當內存不足的時候,會自動清理緩存
程序開始時,可以指定緩存的數量 & 成本
方法

取值
- (id)objectForKey:(id)key;
設置對象,0成本
- (void)setObject:(id)obj forKey:(id)key;
設置對象並指定成本
- (void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)g;

成本示例,以圖片爲例:

方案一:緩存 100 張圖片
方案二:總緩存成本設定爲 10M,以圖片的 寬 * 高當作成本,圖像像素。這樣,無論緩存的多少張照片,只要像素值超過 10M,就會自動清理
結論:在緩存圖像時,使用成本,比單純設置數量要科學!
刪除
- (void)removeObjectForKey:(id)key;
刪除全部
- (void)removeAllObjects;
屬性

緩存總成本
@property NSUInteger totalCostLimit;

緩存總數量
@property NSUInteger countLimit;

是否自動清理緩存,默認是 YES
@property BOOL evictsObjectsWithDiscardedContent;

代碼演練

定義緩存屬性
@property (nonatomic, strong) NSCache *cache;
懶加載並設置限制
- (NSCache *)cache {
    if (_cache == nil) {
        _cache = [[NSCache alloc] init];
        _cache.delegate = self;
        _cache.countLimit = 10;
    }
    return _cache;
}
觸摸事件添加緩存
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    for (int i = 0; i < 20; ++i) {
        NSString *str = [NSString stringWithFormat:@"%d", i];
        NSLog(@"set -> %@", str);
        [self.cache setObject:str forKey:@(i)];
        NSLog(@"set -> %@ over", str);
    }

    // 遍歷緩存
    NSLog(@"------");

    for (int i = 0; i < 20; ++i) {
        NSLog(@"%@", [self.cache objectForKey:@(i)]);
    }
}

// 代理方法,僅供觀察使用,開發時不建議重寫此方法
- (void)cache:(NSCache *)cache willEvictObject:(id)obj {
    NSLog(@"remove -> %@", obj);
}
//修改網絡圖片框架

//修改圖像緩衝池類型,並移動到 .h 中,以便後續測試
///  圖像緩衝池
@property (nonatomic, strong) NSCache *imageCache;
//修改懶加載,並設置數量限制
- (NSCache *)imageCache {
    if (_imageCache == nil) {
        _imageCache = [[NSCache alloc] init];
        _imageCache.countLimit = 15;
    }
    return _imageCache;
}
//修改其他幾處代碼,將 self.imageCache[URLString] 替換爲 [self.imageCache setObject:image forKey:URLString];

//測試緩存中的圖片變化

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    for (AppInfo *app in self.appList) {
        NSLog(@"%@ %@", [[DownloadImageManager sharedManager].imageCache objectForKey:app.icon], app.name);
    }
}
//註冊通知,監聽內存警告
- (instancetype)init
{
    self = [super init];
    if (self) {
        // 註冊通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(clearMemory) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
    }
    return self;
}

// 提示:雖然執行不到,但是寫了也無所謂
- (void)dealloc {
    // 刪除通知
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
//清理內存
- (void)clearMemory {
    NSLog(@"%s", __FUNCTION__);

    // 取消所有下載操作
    [self.downloadQueue cancelAllOperations];

    // 刪除緩衝池
    [self.operationChache removeAllObjects];
}
**注意:內存警告或者超出限制後,緩存中的任何對象,都有可能被清理**。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章