您的位置:首页 > 理论基础 > 计算机网络

HTTP协议(三)之缓存

2015-07-22 09:55 253 查看
当我们对容一个URL可能多次请求,并且请求返回的数据都是一样的,比如服务器上的图片,无论下载多少次都是一样的,这个时候我们就可以使用缓存,优点主要有两点:

1、避免用户浪费流量 2、提高程序的响应速度

缓存分为内存缓存(沙盒缓存)和硬盘缓存。当我们第一次请求数据时,先检查内存缓存中有没有缓存数据,如果有就直接使用内存缓存中的数据,如果没有就检查硬盘缓存中有无缓存数据,如果有就使用,如果没有就向服务器请求数据。当服务器返回数据后,先使用返回的数据,然后将返回的数据缓存到硬盘中。此时再次请求这个数据就可以直接使用内存中的缓存了。

在HTTP协议中,GET请求一般用来请求数据,而POST一般用来给服务器发送大量数据,所以我们一般对GET请求的数据进行缓存,不必对POST请求进行缓存。

在iOS中,可以使用NSURLCache进行缓存。iOS中使用缓存策略来使用不同的缓存方案,提供了7种缓存策略:



NSURLRequestUseProtocolCachePolicy:默认的缓存策略,取决于HTTP协议中是否需要缓存。

NSURLRequestReloadIgnoringLocalCacheData:忽略缓存,重新请求。

NSURLRequestReloadIgnoringLocalAndRemoteCacheData:未实现

NSURLRequestReloadIgnoringCacheData:和第2种相同。

NSURLRequestReturnCacheDataElseLoad:有缓存使用缓存,没有就重新请求。

NSURLRequestReturnCacheDontLoad:只使用缓存,不发送请求(用于离线模式)

NSURLRequestReloadRevalidatingCacheData:未实现

我们在开发时一般使用NSURLRequestReturnCacheDataElseLoad缓存策略,当我们发送请求返回数据后,数据会再内存和沙盒中缓存,再次请求这个数据的时候会从内存或者沙盒中取出数据,不再向服务器发送请求。

- (IBAction)getData:(id)sender {

//创建请求
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/video?method=get&type=JSON"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

//设置缓存策略
request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;

//发送请求,获得数据
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(@"dict:%@", dict);
}];
}


NSURLCache是一个非常重要的单例,它管理应用的所有缓存和缓存的属性设置。

获取/设置缓存大小:

- (NSUInteger)memoryCapacity;

/*!
@method diskCapacity
@abstract Returns the on-disk capacity of the receiver.
@result The on-disk capacity, measured in bytes, for the receiver.
*/
- (NSUInteger)diskCapacity;

/*!
@method setMemoryCapacity:
@abstract Sets the in-memory capacity of the receiver.
@discussion At the time this call is made, the in-memory cache will
truncate its contents to the size given, if necessary.
@param memoryCapacity the new in-memory capacity, measured in
bytes, for the receiver.
*/
- (void)setMemoryCapacity:(NSUInteger)memoryCapacity;

/*!
@method setDiskCapacity:
@abstract Sets the on-disk capacity of the receiver.
@discussion At the time this call is made, the on-disk cache will
truncate its contents to the size given, if necessary.
@param diskCapacity the new on-disk capacity, measured in
bytes, for the receiver.
*/
- (void)setDiskCapacity:(NSUInteger)diskCapacity;


内存使用量:

/*!
@method currentMemoryUsage
@abstract Returns the current amount of space consumed by the
in-memory cache of the receiver.
@discussion This size, measured in bytes, indicates the current
usage of the in-memory cache.
@result the current usage of the in-memory cache of the receiver.
*/
- (NSUInteger)currentMemoryUsage;

/*!
@method currentDiskUsage
@abstract Returns the current amount of space consumed by the
on-disk cache of the receiver.
@discussion This size, measured in bytes, indicates the current
usage of the on-disk cache.
@result the current usage of the on-disk cache of the receiver.
*/
- (NSUInteger)currentDiskUsage;


清除缓存:

/*!
@method removeCachedResponseForRequest:
@abstract Removes the NSCachedURLResponse from the cache that is
stored using the given request.
@discussion No action is taken if there is no NSCachedURLResponse
stored with the given request.
@param request the NSURLRequest to use as a key for the lookup.
*/
- (void)removeCachedResponseForRequest:(NSURLRequest *)request;

/*!
@method removeAllCachedResponses
@abstract Clears the given cache, removing all NSCachedURLResponse
objects that it stores.
*/
- (void)removeAllCachedResponses;


获取/保存某个请求的缓存:

/*!
@method cachedResponseForRequest:
@abstract Returns the NSCachedURLResponse stored in the cache with
the given request.
@discussion The method returns nil if there is no
NSCachedURLResponse stored using the given request.
@param request the NSURLRequest to use as a key for the lookup.
@result The NSCachedURLResponse stored in the cache with the given
request, or nil if there is no NSCachedURLResponse stored with the
given request.
*/
- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request;

/*!
@method storeCachedResponse:forRequest:
@abstract Stores the given NSCachedURLResponse in the cache using
the given request.
@param cachedResponse The cached response to store.
@param request the NSURLRequest to use as a key for the storage.
*/
- (void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NSURLRequest *)request;


我们可以用下面这个方法手动获取某个请求:

- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request;


NSCachedURLResponse就是一个请求对应的缓存对象,从这个缓存对象中可以获取对应的缓存数据:

/*!
@method data
@abstract Returns the data of the receiver.
@result The data of the receiver.
*/
- (NSData *)data;


下面是一个获取天气信息的demo,使用NSURLRequestReturnCacheDataElseLoad缓存策略:

- (IBAction)getData:(id)sender {

//创建请求
NSURL *url = [NSURL URLWithString:@"http://www.weather.com.cn/adat/cityinfo/101010100.html"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

//设置缓存策略
request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;

//获取缓存数据
NSURLCache *cache = [NSURLCache sharedURLCache];
NSCachedURLResponse *cachedResponse = [cache cachedResponseForRequest:request];
if (cachedResponse) {
NSData *data = cachedResponse.data;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(@"有缓存数据:%@", dict);
}else {
NSLog(@"没有缓存数据");
}

//发送请求,获得数据
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(@"dict:%@", dict);
}];
}


第一次请求的输出:

2015-07-10 09:56:59.249 CacheDemo[21401:607] 没有缓存数据
2015-07-10 09:56:59.438 CacheDemo[21401:607] dict:{
weatherinfo =     {
city = "U5317U4eac";
cityid = 101010100;
img1 = "d1.gif";
img2 = "n1.gif";
ptime = "08:00";
temp1 = "15U2103";
temp2 = "5U2103";
weather = "U591aU4e91";
};
}


再次请求的输出:

2015-07-10 09:57:34.057 CacheDemo[21423:607] 有缓存数据:{
weatherinfo =     {
city = "U5317U4eac";
cityid = 101010100;
img1 = "d1.gif";
img2 = "n1.gif";
ptime = "08:00";
temp1 = "15U2103";
temp2 = "5U2103";
weather = "U591aU4e91";
};
}
2015-07-10 09:57:34.063 CacheDemo[21423:607] dict:{
weatherinfo =     {
city = "U5317U4eac";
cityid = 101010100;
img1 = "d1.gif";
img2 = "n1.gif";
ptime = "08:00";
temp1 = "15U2103";
temp2 = "5U2103";
weather = "U591aU4e91";
};
}


OK,可以使用缓存数据了。如果缓存数据过期那就要清除缓存,下面是清除缓存的实例:

- (IBAction)clearCache:(id)sender {
//清除所有缓存
NSLog(@"清除所有缓存");
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}


清除缓存后再次发送请求的输出:

2015-07-10 10:03:17.266 CacheDemo[21547:607] 清除所有缓存
2015-07-10 10:03:18.659 CacheDemo[21547:607] 没有缓存数据
2015-07-10 10:03:19.765 CacheDemo[21547:607] dict:{
weatherinfo =     {
city = "U5317U4eac";
cityid = 101010100;
img1 = "d1.gif";
img2 = "n1.gif";
ptime = "08:00";
temp1 = "15U2103";
temp2 = "5U2103";
weather = "U591aU4e91";
};
}


下面这个流程图很好的展示了如何使用缓存:



最后是Demo的下载地址:CacheDemo
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: