• IOS开发 网络发展史(NSURLCach)


    NSURLCach工作原理

    1. 请求前的配置,包括请求头,响应头,超时时间以及缓存策略 ( 后面会说到有关缓存策略 ) 。
    
    2. 真正去服务器请求前,判断缓存策略,调用 cachedResponseForRequest: ( NSURLRequest * ) request 方法试着取缓存或者直接请求网络。
    
    3. 如果缓存策略允许取缓存,并且取到了缓存,请求成功并且返回缓存数据。
    
    4. 如果缓存策略允许取缓存,并且没有取到缓存,再次判断缓存策略,如果缓存策略允许联网,则联网请求,否则,请求失败。
    
    5. 上述 23 任何一种请求成功的话,判断缓存策略和服务器返回的响应头。如果允许存储,则调用 storeCachedResponse: ( NSCachedURLResponse * ) cachedResponse forRequest: ( NSURLRequest * ) request 将返回的数据存储到内存以及硬盘,否则,直接返回请求成功。

    NSURLCach的缓存策略(缓存和请求的自由组合)

    如果使用了默认缓存策略,也就是上面表格中第一个,需要从返回的 response 的 header 中获取相应的字段来指导缓存该如何进行。
    1.Cache-Control 字段:常用的有 no-cache,no-store,和 max-age。其中 no-cache 代表不能使用这个缓存,no-store 代表不存储这个数据,max-age 代表缓存的有效期 ( 单位为秒 ) 。
    
    2.Expires 字段:缓存过期时间,后面跟一个日期,此日期之前都可以直接使用本缓存。如果 Expires 与 Cache-Control 同时存在,则 Cache-Control 优先。
    
    3.Last-Modified 和 If-Modified-Since 字段:如果 response 中有 Last-Modified,则在下次请求时,给 request 的 header 设置 If-Modified-Since 为 Last-Modified 的值,服务器校验数据是否有变化,如果有变化,返回新数据,否则,返回 304 状态码,可以使用此缓存。
    
    4.ETag 和 If-None-Match 字段:如果 response 中有 ETag,则在下次请求时,给 request 的 header 设置 If-None-Match 为 ETag 的值,服务器校验数据是否有变化,如果有变化,返回新数据,否则,返回 304 状态码,可以使用此缓存。

    使用的步骤

    1.配置自定义缓存类

    NSUInteger memoryCapacity = 20*1024*1024;
    NSUInteger diskCapacity
    = 50*1024*1024;
    WXYURLCache
    *customURLCache = [[WXYURLCache alloc] initWithMemoryCapacity:memoryCapacity diskCapacity:diskCapacity diskPath:[WXYURLCache customCachePath]]; [NSURLCache setSharedURLCache:customURLCache];

    设置缓存的类型(内存和硬盘),缓存的大小,缓存的位置,缓存的策略

    2.设置请求

    + (void)requestWithSuccess:(SuccessBlock)success failure:(failureBlock)failure{
     
        AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager manager];
        //配置请求头
        sessionManager.requestSerializer = [AFHTTPRequestSerializer serializer];
        sessionManager.requestSerializer.cachePolicy = [self getCachePolicy];//缓存策略
        //配置响应头
        sessionManager.responseSerializer = [AFJSONResponseSerializer serializer];
     
        [sessionManager GET:customURLString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            NSLog(@"
    请求成功:
     
    URL:%@
      
    response:%@
    
    ", task.currentRequest.URL.absoluteString, responseObject);
            success(responseObject);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"
    请求失败: 
     
    URL:%@
      
    error:%@
    
    ", task.currentRequest.URL.absoluteString, [error.userInfo objectForKey:@"NSLocalizedDescription"]);
            failure(error);
        }];
     
    }

    3.重写缓存的方法(取缓存和存缓存)

    - (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request{
        NSCachedURLResponse *cachedURLResponse = [super cachedResponseForRequest:request];
        id cacheData = nil;
        if (!cachedURLResponse.data) {
            cacheData = @"取到的缓存为空";
        }
        else{
            cacheData = [NSJSONSerialization JSONObjectWithData:cachedURLResponse.data options:NSJSONReadingMutableContainers error:nil];
        }
     
        NSLog(@"
    取缓存:
      
    URL:%@
      
    response:%@
    
    ", request.URL.absoluteString, cacheData);
     
        return cachedURLResponse;
    }
    - (void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NSURLRequest *)request{
        id cacheData = [NSJSONSerialization JSONObjectWithData:cachedResponse.data options:NSJSONReadingMutableContainers error:nil];
     
        NSLog(@"
    存缓存:
      
    URL:%@
      
    response:%@
    
    ", request.URL.absoluteString, cacheData);
     
        [super storeCachedResponse:cachedResponse forRequest:request];
    }

    伪造响应

    NSLog(@"%@",[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]);
        
        
    NSURLRequest
    *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://172.16.25.44/test1.php"] cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:3]; NSURLCache * cache = [NSURLCache sharedURLCache]; NSData *contentData = [@"123" dataUsingEncoding:NSUTF8StringEncoding]; NSURLResponse *response = [[NSURLResponse alloc] initWithURL:[NSURL URLWithString:@"http://172.16.25.44/test1.php"] MIMEType:@"text/html" expectedContentLength:1000 textEncodingName:@"UTF-8"]; NSCachedURLResponse *cacheRespone = [[NSCachedURLResponse alloc] initWithResponse:response data:contentData];
    [cache storeCachedResponse:cacheRespone forRequest:request]; connection
    = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [connection start];

    修改响应内容


    想要修改内容,要实现NSConnectionDataDelegate方法的willCachResponse方法

    -(NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse { NSMutableData *mutableData = [[cachedResponse data] mutableCopy]; //添加数据 NSCachedURLResponse *response = [[NSCachedURLResponse alloc] initWithResponse:cachedResponse.response data:mutableData]; return response; }
  • 相关阅读:
    MyEclipse中的几种查找方法
    WebLogic初学笔记
    CountDownLatch源码分析
    linux--句柄相关
    linux命令--wc
    Spring源码解析(九)--再来说说三级缓存
    定位JVM内存泄漏常用命令和方法
    Mybatis整合Spring之MapperFactoryBean怎么拿到的SqlSessionFactory
    Mybatis3.3.0 Po类有LocalDateTime字段报错
    时间范围查询优化技巧
  • 原文地址:https://www.cnblogs.com/guchengfengyun/p/8170819.html
Copyright © 2020-2023  润新知