缘由
前一段时间去仿写SDWebImage
的时候,就遇到这SDCache
和NSURLCache
,然后在类中还有地做了一切判断,当时找了一些相关文章看,但是没有特别理解网络层,对NSURLCache
,NSCache
,ETag
,Last-Modified
表示很模糊;
这几天正在阅读AFNetworking
的源码,然后不得不又遇到这个NSURLCache
,硬着头皮又看了一边之前的文章,又是云里雾里,好在跟着博客写了一个demo,算是理解~
NSURLCache和NSCache有关系吗?
没有,前者是给url做缓存的,可以有内存缓存,也可以有磁盘缓存;后者是对文件缓存,保存到内存中
NSURLCache的使用
普遍来说,这个功能非常强大,两句代码就可以做缓存;
//在整个方法中写
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSURLCache *urlCache = [[NSURLCache alloc] initWithMemoryCapacity:4*1024*1024 diskCapacity:20*1024*1024 diskPath:nil];
[NSURLCache setSharedURLCache:urlCache];
return YES;
}
AFNetworking的作者非常推荐这样使用
并且,AFN的demo中就这样写的,直接作为缓存使用!!!
但是,我们只是缓存了,没有使用缓存!!!这个一定要明确,因为,我们没有每一次发送请求的时候,都没有使用ETag
或者Last-Modified
字段,所以,以后对同一个url做请求,只是做了缓存,但是没有利用缓存;
如何使用url的内存缓存?如何优化自己的网络请求?
说到这里,首先了解一下什么是ETag
和Last-Modified
:
1.ETag是内容摘要,就是内容的MD5,然后和后台比对;在request对应的字段是If-None-Match
2.Last-Modified 是文件上一次修改的时间,但是比较的时候,用!=
,因为有可能后台的文件回退,导致了我们前台发送的时间大约后台的文件修改时间,这个可能经常发生,所以要去处理使用!=
; 在request对应的字段是If-Modified-Since
;
self.imageView.image = nil;
NSURL *url = [NSURL URLWithString:kETagImageURL];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:15.0];
NSLog(@"看看If-Modified-Since = %@",self.localLastModified);
if (self.localLastModified.length>0) {
[request setValue:self.localLastModified forHTTPHeaderField:@"If-Modified-Since"];
}
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode == 304) {
//没改变
NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
data = cachedResponse.data;
NSLog(@"走了304");
}else{
NSLog(@"走了200");
//保存last_modified
self.localLastModified = httpResponse.allHeaderFields[@"Last-Modified"];
NSLog(@"收到的reponse 修改时间%@",httpResponse.allHeaderFields[@"Last-Modified"]);
}
if (data) {
UIImage *image = [[UIImage alloc] initWithData:data];
self.imageView.image = image;
}
}];
[task resume];