NSURLCache 笔记

121 阅读2分钟

NSURLCache 的使用

定义

The NSURLCache class implements the caching of responses to URL load requests by mapping NSURLRequest objects to NSCachedURLResponse objects. It provides a composite in-memory and on-disk cache, and lets you manipulate the sizes of both the in-memory and on-disk portions. You can also control the path where cache data is stored persistently.

上面是NSURLCache 官方的一段说明,原理是通过NSURLRequest 去查找request,他提供了在内存和磁盘中的缓存,可以允许你设置在内存和磁盘的中大小,你也可以控制这些data 数据的存放路径.

缓存策略

当使用 NSURLSession 时 , 我们可以直接通过 NSMutableURLRequest 来指定 NSURLRequestCachePolicy .

typedef NS_ENUM(NSUInteger, NSURLRequestCachePolicy)
{
    NSURLRequestUseProtocolCachePolicy = 0, //默认策略

    NSURLRequestReloadIgnoringLocalCacheData = 1, //忽略缓存,必须从远程地址下载;
    NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // Unimplemented 未实现
    NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,

    NSURLRequestReturnCacheDataElseLoad = 2, // 无论缓存是否过期 , 有就使用缓存 , 没有就请求数据.
    NSURLRequestReturnCacheDataDontLoad = 3,// 无论缓存是否过期 , 有就使用缓存 , 没有就请求失败.

    NSURLRequestReloadRevalidatingCacheData = 5, // Unimplemented 未实现
};

默认的是NSURLRequestUseProtocolCachePolicy 的策略就是HTTP 协议的,这是什么协议呢?

默认使用的HTTP 缓存策略是什么呢? 先看一个例子

- (void)example_1{
    NSURL *url = [NSURL URLWithString:@"http://via.placeholder.com/50x50.jpg"];
    //默认使用 HTTP缓存策略来进行缓存
     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            NSLog(@"error warning : %@",error);
        }else{
            //从缓存当中读取数据!
            NSData *tempData = data;
            NSString *responseStr = [[NSString alloc] initWithData:tempData encoding:NSUTF8StringEncoding];
            NSLog(@"response:%@",response);
        }
    }] resume];
    
}

最后的结果

response:<NSHTTPURLResponse: 0x600002ff7380> { URL: http://via.placeholder.com/50x50.jpg } { Status Code: 200, Headers {
    "Accept-Ranges" =     (
        bytes
    );
    "Cache-Control" =     (
        "max-age=604800"
    );
    Connection =     (
        "keep-alive"
    );
    "Content-Length" =     (
        807
    );
    "Content-Type" =     (
        "image/jpeg"
    );
    Date =     (
        "Wed, 18 Sep 2019 06:32:38 GMT"
    );
    Etag =     (
        "\"5d5c8aae-327\""
    );
    Expires =     (
        "Wed, 25 Sep 2019 06:32:38 GMT"
    );
    "Last-Modified" =     (
        "Wed, 21 Aug 2019 00:05:02 GMT"
    );
    Server =     (
        "nginx/1.6.2"
    );
    "X-Cache" =     (
        L1
    );
} }

其实在 HTTP 中,控制缓存开关的字段有两个:Pragma 和 Cache-Control . Pragma 是旧产物,已经逐步抛弃,有些网站为了向下兼容还保留了这两个字段. 在此就不介绍了. 可以根据cache-control进行协商缓存.

缓存校验主要是用Last-Modified 和 etag 这两个字段.

HTTP 缓存机制总结

缓存开关是: pragma , cache-control.

缓存校验有:Expires , Last-Modified , etag.

第一次请求: 请求,协商缓存. 第二次: 没有缓存,直接请求. 有缓存,过期了,直接请求. 有缓存,没过期,通过Last-Modified 和etag去服务器,让服务器去决策,还是原来的资源,返回304,让客户端用本地,否则用响应返回给客户端.

总结

其实ios开发对于图片的缓存,和音视频的资源的缓存是可以用系统的这个NSURLCache 的方式,当时这个方式还是有一些不太灵活,所以才用了SDWebImageView 这种东西的用武之地.