iOS NSCache

作者: __Mr_Xie__ | 来源:发表于2019-07-03 18:48 被阅读1次

    NSCache 概述

    • NSCache 是一个类似 NSDictionary一个可变的集合。
    • 提供了可设置缓存的数目与内存大小限制的方式。
    • 保证了处理的数据的线程安全性。
    • 缓存使用的 key 不需要是实现 NSCopying 的类。
    • 当内存警告时内部自动清理部分缓存数据。
      注:详情见 Apple 文档

    API

    常用属性

    • totalCostLimit:设置缓存的数据占用内存大小,超过这个数值,系统会自动回收之前的对象;
    • countLimit:设置最多可以缓存多少个数据;

    常用方法

    • - (nullable ObjectType)objectForKey:(KeyType)key;
    • - (void)setObject:(ObjectType)obj forKey:(KeyType)key; // 0 cost
    • - (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g;
    • - (void)removeObjectForKey:(KeyType)key;

    注:totalCostLimit 属性需要跟方法 - (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g 搭配使用的,否则单独设置totalCostLimit不会生效。

    代理 - NSCacheDelegate

    - (void)cache:(NSCache *)cache willEvictObject:(id)obj;

    注:这个代理方法是可选的(@optional),当删除缓存数据时,会调用这个代理方法。

    NSCache 简单使用

    #import "ViewController.h"
    
    @interface ViewController () <NSCacheDelegate>
    
    @property (nonatomic, strong) NSCache *cache;
    
    @end
    
    @implementation ViewController
    
    
    - (IBAction)addBtnClick:(UIButton *)sender {
        NSLog(@"%@", NSHomeDirectory());
        
        for (NSInteger i = 0; i < 6; ++i) {
            NSString *path = [[NSBundle mainBundle] pathForResource:@"xx" ofType:@"jpg"];
            NSData *imgData = [NSData dataWithContentsOfFile:path];
    //        [self.cache setObject:imgData forKey:@(i)];
            // 可以设置cost为1、2或者其他
            [self.cache setObject:imgData forKey:@(i) cost:1];
            
            NSLog(@"存数据 -- %zd", i);
        }
    }
    
    - (IBAction)checkBtnClick:(UIButton *)sender {
        NSLog(@"\n\n\n--------------------------------------\n\n\n");
        for (NSInteger i = 0; i < 10; ++i) {
            NSData *imgData = [self.cache objectForKey:@(i)];
            if (imgData) {
                NSLog(@"取出数据 -- %zd", i);
            }
        }
    }
    
    - (IBAction)clearBtnClick:(UIButton *)sender {
        [self.cache removeAllObjects];
    }
    
    #pragma mark - NSCacheDelegate
    - (void)cache:(NSCache *)cache willEvictObject:(id)obj {
        NSLog(@"释放---%@", obj);
    }
    
    - (NSCache *)cache {
        if (_cache == nil) {
            _cache = [[NSCache alloc] init];
            // 设置缓存的数据占用内存大小,超过这个数值,系统会自动回收之前的对象
            // totalCostLimit属性需要跟方法- (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g搭配使用的,否则不会生效
            _cache.totalCostLimit = 3;
            // 设置最多可以缓存多少个数据
    //        _cache.countLimit = 4;
            _cache.delegate = self;
        }
        return _cache;
    }
    @end
    

    NSCache 内存警告的处理思路

    自定义一个类继承自 NSCache,在这个自定义类添加 UIApplicationDidReceiveMemoryWarningNotification 通知,代码如下:

    // 继承NSCache,实现自定义的cache类
    @interface XWCache : NSCache
    @end
    
    @implementation XWCache
    
    - (id)init
    {
        self = [super init];
        if (self) {
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
        }
        return self;
    }
    
    - (void)dealloc
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
    
    }
    @end
    

    Author

    如果你有什么建议,可以关注我的公众号:iOS开发者进阶,直接留言,留言必回。

    相关文章

      网友评论

        本文标题:iOS NSCache

        本文链接:https://www.haomeiwen.com/subject/twychctx.html