SDWebImage(NSURLCache/NSCache)探究

NSCache的特点

  • 使用方便,类似字典
  • 线程安全
  • NSCache的 key 不会被拷贝,不需要实现 Coping 协议
  • NSCache自动释放对象
    • 手动调用removeObjectForKey:方法
    • 手动调用removeAllObjects
    • 缓存中对象的个数大于countLimit,或,缓存中对象的总cost值大于totalCostLimit
    • 程序进入后台后
  • evictsObjectsWithDiscardedContent,这个值与NSDiscardableContent协议有关,默认为YES,当一个类实现了该协议,并且这个类的对象不再被使用时意味着可以被释放
_cache = [[NSCache alloc] init];
NSLog(@"evictsObjectsWithDiscardedContent: %d",_cache.evictsObjectsWithDiscardedContent);
// evictsObjectsWithDiscardedContent: 1

在这里插入图片描述

NSCache示例

在这里插入图片描述

  • 注意:默认情况下,当一个NSPurgeableData对象初始化的时候,它的引用计数变量值为1,并且可以安全的被访问。为了访问这个purgeable memory,仅仅调用 beginContentAccess方法即可。这个方法首先会检查这个对象的数据是否被销毁。如果这个数据仍然在,它将会增加这个对象指向的内存的引用计数,并且返回YES。如果这个对象的数据已经被销毁了,这个方法就会返回NO。当我们完成对这个对象的访问后,调用endContentAccess方法即可,这个方法会减少这块内存区域的引用计数,并允许内存在需要是释放它。只有当 beginContentAccess方法返回YES时,我们才可以去访问这个对象所指向的内存空间
  • 当系统可用内存减少时,系统或客户端对象通过调用discardContentIfPossible方法来销毁purgeable数据,当对象所指向的内存引用计数为0时,这个方法仅仅会销毁上面的数据,然后不再做其它任何操作。如果这个内存被销毁了,那么 isContentDiscarded方法会返回YES。

NSURLCache探究

  • NSURLRequestCachePolicy 常见缓存策略
    • NSURLRequestUseProtocolCachePolicy 默认的策略。

    • 在这里插入图片描述

    • NSURLRequestReloadIgnoringLocalCacheData URL应该加载源端数据,不使用本地缓存数据

    • NSURLRequestReturnCacheDataElseLoad Specifies that the
      existing cache data should be used to satisfy a URL load request,
      regardless of its age or expiration date. However, if there is no
      existing data in the cache corresponding to a URL load request,
      the URL is loaded from the origin source

    • NSURLRequestReturnCacheDataDontLoad Specifies that the
      existing cache data should be used to satisfy a URL load request,
      regardless of its age or expiration date. However, if there is no
      existing data in the cache corresponding to a URL load request, no
      attempt is made to load the URL from the origin source, and the
      load is considered to have failed. This constant specifies a
      behavior that is similar to an “offline” mode.

  • http中的Cache-Control浅谈
    • max-age:缓存时间
    • public:谁都可以缓存
    • private:只有客户端缓存,中间代理无法缓存
    • no-cache:服务端进行确认
    • no-store:禁止使用缓存
  • Last-Modified
    • 服务端在返回资源时,会将该资源的最后更改时间通过Last-Modified字段返回给客户端。客户端下次请求时通过If-Modified-Since或者If-Unmodified-Since带上Last-Modified,服务端检查该时间是否与服务器的最后修改时间一致:如果一致,则返回304状态码,不返回资源;如果不一致则返回200和修改后的资源,并带上新的时间。
    • If-Modified-Since和If-Unmodified-Since的区别是:
    • If-Modified-Since:告诉服务器如果时间一致,返回状态码304
    • If-Unmodified-Since:告诉服务器如果时间不一致,返回状态码412
  • etag
    • 单纯的以修改时间来判断还是有缺陷,比如文件的最后修改时间变了,但内容没变。对于这样的情况,我们可以使用etag来处理。etag的方式是这样:服务器通过某个算法对资源进行计算,取得一串值(类似于文件的md5值),之后将该值通过etag返回给客户端,客户端下次请求时通过If-None-Match或If-Match带上该值,服务器对该值进行对比校验:如果一致则不要返回资源。
    • If-None-Match和If-Match的区别是:
    • If-None-Match:告诉服务器如果一致,返回状态码304,不一致则返回资源
    • If-Match:告诉服务器如果不一致,返回状态码412
  • 示例
NSURL *url = [NSURL URLWithString:@"https://www.baidu.com/img/dong_a16028f60eed614e4fa191786f32f417.gif"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15.0];
    //比对服务,资源是否更新
    if (self.lastModified) {
        [request setValue:self.lastModified forHTTPHeaderField:@"If-Modified-Since"];
    }
//    if (self.etag) {
//        [request setValue:self.etag forHTTPHeaderField:@"If-None-Match"];
//    }
    [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        
        if (error) {
            NSLog(@"error warning : %@",error);
        }else{
            NSHTTPURLResponse *urlRes = (NSHTTPURLResponse *)response;
            NSLog(@"response:%ld",(long)urlRes.statusCode);
            NSLog(@"---: %@",urlRes);
            self.lastModified = [(NSHTTPURLResponse *)response allHeaderFields][@"Last-Modified"];
//            self.etag = [(NSHTTPURLResponse *)response allHeaderFields][@"Etag"];
        }
    }] resume];
  • 第二次刷新时根据Last-Modified对比服务器资源
2019-09-25 16:31:25.697014+0800 LGURCacheTest[14904:1023083] response:304
2019-09-25 16:31:25.697164+0800 LGURCacheTest[14904:1023083] ---: <NSHTTPURLResponse: 0x600000bc1620> { URL: https://www.baidu.com/img/dong_a16028f60eed614e4fa191786f32f417.gif } { Status Code: 304, Headers {
    "Cache-Control" =     (
        "max-age=315360000"
    );
    Connection =     (
        "Keep-Alive"
    );
    Date =     (
        "Wed, 25 Sep 2019 08:31:25 GMT"
    );
    Etag =     (
        "\"79353-5933a8157f6dc\""
    );
    Expires =     (
        "Sat, 22 Sep 2029 08:31:25 GMT"
    );
    Server =     (
        Apache
    );
} }
2019-09-25 16:31:25.697242+0800 LGURCacheTest[14904:1023083] ---: (null)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值