緣由
前一段時間去仿寫SDWebImage的時候,就遇到這SDCache和NSURLCache,然后在類中還有地做了一切判斷,當(dāng)時找了一些相關(guān)文章看,但是沒有特別理解網(wǎng)絡(luò)層,對NSURLCache,NSCache,ETag,Last-Modified表示很模糊;
這幾天正在閱讀AFNetworking的源碼,然后不得不又遇到這個NSURLCache,硬著頭皮又看了一邊之前的文章,又是云里霧里,好在跟著博客寫了一個demo,算是理解~
NSURLCache和NSCache有關(guān)系嗎?
沒有,前者是給url做緩存的,可以有內(nèi)存緩存,也可以有磁盤緩存;后者是對文件緩存,保存到內(nèi)存中
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中就這樣寫的,直接作為緩存使用!!!
但是,我們只是緩存了,沒有使用緩存?。?!這個一定要明確,因為,我們沒有每一次發(fā)送請求的時候,都沒有使用ETag或者Last-Modified字段,所以,以后對同一個url做請求,只是做了緩存,但是沒有利用緩存;
如何使用url的內(nèi)存緩存?如何優(yōu)化自己的網(wǎng)絡(luò)請求?
說到這里,首先了解一下什么是ETag和Last-Modified:
1.ETag是內(nèi)容摘要,就是內(nèi)容的MD5,然后和后臺比對;在request對應(yīng)的字段是If-None-Match
2.Last-Modified 是文件上一次修改的時間,但是比較的時候,用!=,因為有可能后臺的文件回退,導(dǎo)致了我們前臺發(fā)送的時間大約后臺的文件修改時間,這個可能經(jīng)常發(fā)生,所以要去處理使用!=; 在request對應(yīng)的字段是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];
參考文章:
1.使用80%的代碼來完成剩下的20%的緩存需求
2.NSCache和NSURLCache、網(wǎng)絡(luò)緩存優(yōu)化