zoukankan      html  css  js  c++  java
  • 【IOS】ASIDownloadCache缓存策略

     在我们实际工程中,很多情况需要从网络上加载图片,然后将图片在imageview中显示出来,但每次都要从网络上请求,会严重影响用户体验,为了不是每次显示都需要从网上下载数据,希望将图片放到本地缓存,因此我们需要一个好的的缓存策略,今天我将我在项目工程中的实际经验分享给大家,我这里主要介绍一下强大的ASIHTTPRequest的缓存策略,以及使用方法:

     下面是具体步骤:

        一、设置缓存策略

        首先在SplitDemoAppDelegate委托代理中,实现如下代码:

        在SplitDemoAppDelegate.h文件中,代码如下:

     1 #import <UIKit/UIKit.h>
     2 
     3 @class ASIDownloadCache;
     4 
     5 @interface SplitDemoAppDelegate : NSObject <UIApplicationDelegate,UITabBarControllerDelegate> {
     6 
     7     UIWindow *_window;
     8 
     9     ASIDownloadCache *_downloadCache;            //下载缓存策略
    10 
    11 }
    12 
    13 @property (nonatomic, retain) ASIDownloadCache *downloadCache;
    14 
    15 @end
        在SplitDemoAppDelegate.m文件中,代码如下:
     1 #import "SplitDemoAppDelegate.h"
     2 
     3 
     4 @implementation SplitDemoAppDelegate
     5 
     6 
     7 @synthesize window=_window;
     8 
     9 
    10 @synthesize downloadCache = _downloadCache;
    11 
    12 
    13 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    14 
    15 {
    16 
    17     //初始化ASIDownloadCache缓存对象
    18 
    19    ASIDownloadCache *cache = [[ASIDownloadCache alloc] init];
    20 
    21    self.downloadCache = cache;
    22 
    23   [cache release];
    24 
    25  
    26 
    27    //路径
    28 
    29    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    30 
    31   NSString *documentDirectory = [paths objectAtIndex:0];
    32 
    33  
    34 
    35    //设置缓存存放路径
    36 
    37    [self.downloadCache setStoragePath:[documentDirectory stringByAppendingPathComponent:@"resource"]];
    38 
    39    //设置缓存策略
    40 
    41     [self.downloadCache setDefaultCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];
    42 
    43     // Override point for customization after application launch.
    44 
    45     [self.window makeKeyAndVisible];
    46 
    47     return YES;
    48 
    49 }
    50 
    51 - (void)dealloc
    52 
    53 {
    54 
    55     [_window release];
    56 
    57     [_downloadCache release];
    58 
    59    [super dealloc];
    60 
    61 }
    62 
    63 @end 

        二、创建缓存线程

        这一步是创建一个NSOperation类,实现缓存的方法,代码如下:

        ResourceContainer.h文件实现:

     1 #import <Foundation/Foundation.h>
     2 
     3 #import "ASIHTTPRequest.h"
     4 
     5 #import "SplitDemoAppDelegate.h"
     6 
     7  
     8 
     9 @interface ResourceContainer : NSOperation {
    10 
    11 NSURL *_resourceURL;            //资源请求url
    12 
    13 NSObject *_hostObject;             
    14 
    15 SEL _resourceDidReceive;      //资源接手响应方法  
    16 
    17 SplitDemoAppDelegate *_appDelegate;            //应用委托对象
    18 
    19 ASIHTTPRequest *_httpRequest;            
    20 
    21 UIImageView *_imageView;              
    22 
    23 }
    24 
    25  
    26 
    27 @property (nonatomic, retain) NSURL *resourceURL;
    28 
    29 @property (nonatomic, retain) NSObject *hostObject;
    30 
    31 @property (nonatomic, assign) SEL resourceDidReceive;
    32 
    33 @property (nonatomic, assign) SplitDemoAppDelegate   *appDelegate;
    34 
    35 @property (nonatomic, retain) ASIHTTPRequest *httpRequest;
    36 
    37 @property (nonatomic, retain) UIImageView *imageView;
    38 
    39  
    40 
    41 //http请求回调方法
    42 
    43 -(void)didStartHttpRequest:(ASIHTTPRequest *)request;
    44 
    45 -(void)didFinishHttpRequest:(ASIHTTPRequest *)request;
    46 
    47 -(void)didFailedHttpRequest:(ASIHTTPRequest *)request;
    48 
    49  
    50 
    51 //取消资源请求
    52 
    53 -(void)cancelReourceGet;
    54 
    55 //资源接收回调方法
    56 
    57 -(void)resourceDidReceive:(NSData *)resource;
    58 
    59  
    60 
    61 @end

        ResourceContainer.m文件实现:

      1 #import "ResourceContainer.h"
      2 
      3 #import "HttpConstant.h"
      4 
      5 #import "ASIDownloadCache.h"
      6 
      7  
      8 
      9 @implementation ResourceContainer
     10 
     11  
     12 
     13 @synthesize resourceURL = _resourceURL;
     14 
     15 @synthesize hostObject = _hostObject;
     16 
     17 @synthesize resourceDidReceive = _resourceDidReceive;
     18 
     19 @synthesize appDelegate = _appDelegate;
     20 
     21 @synthesize httpRequest = _httpRequest;
     22 
     23 @synthesize imageView = _imageView;
     24 
     25  
     26 
     27 -(id)init{
     28 
     29 if(self == [super init]){
     30 
     31 self.appDelegate = (SplitDemoAppDelegate *)[[UIApplication sharedApplication] delegate];
     32 
     33 }
     34 
     35 return self;
     36 
     37 }
     38 
     39  
     40 
     41 -(void)main{
     42 
     43 if(self.hostObject == nil)
     44 
     45 return;
     46 
     47  
     48 
     49 if(self.resourceURL == nil){
     50 
     51 [self resourceDidReceive:nil];
     52 
     53 return;
     54 
     55 }
     56 
     57  
     58 
     59 ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:self.resourceURL];
     60 
     61 self.httpRequest = request;
     62 
     63  
     64 
     65 [self.httpRequest setDownloadCache:self.appDelegate.downloadCache];
     66 
     67 [self.httpRequest setDelegate:self];
     68 
     69 [self.httpRequest setDidStartSelector:@selector(didStartHttpRequest:)];
     70 
     71 [self.httpRequest setDidFinishSelector:@selector(didFinishHttpRequest:)];
     72 
     73 [self.httpRequest setDidFailSelector:@selector(didFailedHttpRequest:)];
     74 
     75  
     76 
     77     //发异步请求
     78 
     79 [self.httpRequest startAsynchronous];
     80 
     81 }
     82 
     83  
     84 
     85 - (void)dealloc {
     86 
     87 [_resourceURL release];
     88 
     89 [_hostObject release];
     90 
     91 [_httpRequest release];
     92 
     93 [_imageView release];
     94 
     95  
     96 
     97     [super dealloc];
     98 
     99 }
    100 
    101  
    102 
    103 //开始请求
    104 
    105 -(void)didStartHttpRequest:(ASIHTTPRequest *)request{
    106 
    107 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    108 
    109 }
    110 
    111 //请求成功返回处理结果
    112 
    113 -(void)didFinishHttpRequest:(ASIHTTPRequest *)request{
    114 
    115 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    116 
    117  
    118 
    119     if([request responseStatusCode] == 200 || [request responseStatusCode] == 304){
    120 
    121 //判断是否来自缓存
    122 
    123         if([request didUseCachedResponse]){
    124 
    125 NSLog(@"=========资源请求:%@ 来自缓存============",[self.resourceURL absoluteURL]);
    126 
    127         }else{
    128 
    129             NSLog(@"=========资源请求:图片不来自缓存============");
    130 
    131         }
    132 
    133  
    134 
    135 [self resourceDidReceive:[request responseData]];
    136 
    137 }else {
    138 
    139 [self resourceDidReceive:nil];
    140 
    141     }
    142 
    143 }
    144 
    145 //失败请求返回处理结果
    146 
    147 -(void)didFailedHttpRequest:(ASIHTTPRequest *)request{
    148 
    149 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    150 
    151 [self resourceDidReceive:nil];
    152 
    153 }
    154 
    155 //取消资源请求
    156 
    157 -(void)cancelReourceGet{
    158 
    159 [self.httpRequest cancel];
    160 
    161 }
    162 
    163 //资源接收处理方法
    164 
    165 -(void)resourceDidReceive:(NSData *)resource{
    166 
    167 if([self.hostObject respondsToSelector:self.resourceDidReceive]){
    168 
    169 if(resource != nil && self.imageView != nil){
    170 
    171 self.imageView.image = [UIImage imageWithData:resource];
    172 
    173 }
    174 
    175  
    176 
    177 [self.hostObject performSelectorOnMainThread:self.resourceDidReceive withObject:self.imageViewwaitUntilDone:NO];
    178 
    179 }
    180 
    181 }
    182 
    183  
    184 
    185 @end

        到第二步,我们的缓存策略的设置,以及资源请求和接收数据方法已经构建完毕,下面介绍一下如何使用我们上面创建的NSOperation类

        三、图片请求(利用上面创建的类)

        这里以我的工程为例进行分析:

        在DetailViewController.h声明文件中,

     1 #import <UIKit/UIKit.h>
     2 
     3 
     4 @interface DetailViewController :UIViewController {
     5 
     6  
     7 
     8     NSURL                          *_imageURL;                    //图片url
     9 
    10     NSMutableArray            *_originalIndexArray;        //保存请求图片的号
    11 
    12     NSMutableDictionary     *_originalOperationDic;     //保存图片请求队列
    13 
    14     NSOperationQueue        *_requestImageQueue;    //图片请求队列
    15 
    16  
    17 
    18 }
    19 
    20  
    21 
    22 @property (nonatomic, retain) NSURL                        *imageURL;
    23 
    24 @property (nonatomic, retain) NSMutableArray          *originalIndexArray;
    25 
    26 @property (nonatomic, retain) NSMutableDictionary   *originalOperationDic;
    27 
    28 @property (nonatomic, retain) NSOperationQueue      * requestImageQueue;
    29 
    30  
    31 
    32  
    33 
    34  
    35 
    36 //显示图片信息
    37 
    38 -(void)displayProductImage;
    39 
    40 //根据图片序号显示请求图片资源
    41 
    42 -(void)displayImageByIndex:(NSInteger)index ByImageURL:(NSURL *)url;
    43 
    44  
    45 
    46 //处理图片请求返回信息
    47 
    48 -(void)imageDidReceive:(UIImageView *)imageView;
    49 
    50  
    51 
    52  
    53 
    54  
    55 
    56 @end

         在DetailViewController.m实现文件中,

      1 #import "ProductDetailViewController.h"
      2 
      3 //这里引入在第二步中,我们创建的对象
      4 
      5 #import "ResourceContainer.h"
      6 
      7 @implementation DetailViewController
      8 
      9 @synthesize imageURL = _imageURL;
     10 
     11 
     12 @synthesize originalIndexArray = _originalIndexArray;
     13 
     14 @synthesize originalOperationDic = _originalOperationDic;
     15 
     16 @synthesize requestImageQueue = _requestImageQueue;
     17 
     18 
     19 - (void)viewDidLoad
     20 
     21 {
     22 
     23      [super viewDidLoad];
     24 
     25      NSOperationQueue *tempQueue = [[NSOperationQueue alloc] init];
     26 
     27      self.requsetImageQueue = tempQueue;
     28 
     29      [tempQueue release];
     30 
     31       NSMutableArray *array = [[NSMutableArray alloc] init];
     32 
     33       self.originalIndexArray = array;
     34 
     35       [array release];
     36 
     37        NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
     38 
     39        self.originalOperationDic = dic;
     40 
     41        [dic release];
     42 
     43 }
     44 
     45 
     46 //显示图片信息
     47 
     48 -(void)displayProductImage
     49 
     50 {
     51 
     52     NSURL *url = [NSURL URLWithString:@"http://xxx.xxx.xxx.xxx"];
     53 
     54     //这个是从器返回有图片数目,self.xxxx根据具体的场合
     55 
     56     int imageCount = [self.xxxx.imageNum intValue];
     57 
     58     for (int i=0; i<imageCount; i++) {
     59 
     60         NSString *str1 = @"这里是拼图片请求url,根据实际需求";
     61 
     62         self.imageURL = [url URLByAppendingPathComponent:str1];
     63 
     64         //根据图片号请求资源
     65 
     66         [self displayImageByIndex:i ByImageURL:self.productImageURL];
     67 
     68     }
     69 
     70 }
     71 
     72  
     73 
     74 //根据图片序号显示请求图片资源
     75 
     76 -(void) displayImageByIndex:(NSInteger)index ByImageURL:(NSURL *)url
     77 
     78 {
     79 
     80     NSString *indexForString = [NSString stringWithFormat:@"%d",index];
     81 
     82     //若数组中已经存在该图片编号,说明图片加载完毕,直接返回
     83 
     84     if ([self.originalIndexArray containsObject:indexForString]) {
     85 
     86          return;
     87 
     88     }
     89 
     90     //创建UIImageView对象
     91 
     92     UIImageView *imageView = [[UIImageView alloc] init];
     93 
     94     imageView.tag = index;
     95 
     96     //创建资源请求对象
     97 
     98     ResourceContainer  *imageOperation = [[ResourceContainer alloc] init];
     99 
    100     imageOperation.resourceURL = url;
    101 
    102     imageOperation.hostObject = self;
    103 
    104     //设置收到图片信息处理理方法
    105 
    106     imageOperation.resourceDidReceive = @selector(imageDidReceive:);
    107 
    108     imageOperation.imageView = imageView;
    109 
    110     [imageView release];
    111 
    112     //将图片请求对象加入图片请求队列中
    113 
    114     [self.requsetImageQueue addOperation:imageOperation];
    115 
    116     [self.originalOperationDic setObject:imageOperation forKey:indexForString];
    117 
    118     [imageOperation release];
    119 
    120 }
    121 
    122 
    123 //处理图片请求返回信息
    124 
    125 -(void)imageDidReceive:(UIImageView *)imageView
    126 
    127 {
    128 
    129     if (imageView == nil||imageView.image == nil) {
    130 
    131             imageView.image = [UIImage imageNamed:@"no-pic-300-250.png"];
    132 
    133      }
    134 
    135     //将图片信息加载到前台,self.openFlowView是我用的coverFlow,coverFlow的使用方法网上很多,自己找吧
    136 
    137     [self.openFlowView setImage:imageView.image forIndex:imageView.tag];
    138 
    139     [self.originalIndexArray addObject:[NSString stringWithFormat:@"%d",imageView.tag]];
    140 
    141     [self.originalOperationDic removeObjectForKey:[NSString stringWithFormat:@"%d",imageView.tag]];
    142 
    143 }
    144 
    145 
    146 - (void)dealloc
    147 
    148 {
    149 
    150      [_requestImageQueue release];
    151 
    152      [_originalIndexArray release];
    153 
    154      [_originalOperationDic release];
    155 
    156      [_imageURL release];
    157 
    158      [super dealloc];
    159 
    160 }
    161 
    162 @end

        经过上述步骤,我们实现了加载网络图片时缓存功能,增强了用户体验效果。代码中可能会有诸多问题,希望网友指教,有更好的缓存方法,也希望一起交流!

  • 相关阅读:
    SpringBoot基本配置
    Profile配置
    vue2.X使用LeanCloud
    Vue学习一 创建项目及项目总览
    工具使用:使用frp,反向代理内网到公网
    Unity的学习笔记(摇杆制作)
    Unity的学习笔记(XLua的初学用法并在lua中使用unity周期函数)
    Unity的学习笔记(射线检测)
    Unity的学习笔记(鼠标移动控制视角移动)
    Unity的学习笔记(UGUI文本逐个字输出)
  • 原文地址:https://www.cnblogs.com/DannyApple/p/3960884.html
Copyright © 2011-2022 走看看