• HTTP协议(三)之缓存


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

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

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

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

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

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

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

    3. NSURLRequestReloadIgnoringLocalAndRemoteCacheData:未实现

    4. NSURLRequestReloadIgnoringCacheData:和第2种相同。

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

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

    7. 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

  • 相关阅读:
    TLB原理
    64寄存器位查看器
    araxis Merge
    start_KERNEL
    python 动态支持方案
    https://wenku.baidu.com/view/6142875b804d2b160b4ec06b.html 编译原理课件
    有无符号数的区别
    vim工具的路径
    edraw软件破解密钥已经上传,见文件目录
    https://tieba.baidu.com/p/2248070024
  • 原文地址:https://www.cnblogs.com/arthas/p/4666470.html
Copyright © 2020-2023  润新知