您的位置:首页 > 移动开发 > IOS开发

iOS 使用ASI实现图片的缓存机制

2014-10-10 14:51 232 查看
在我们实际工程中,很多情况需要从网络上加载图片,然后将图片在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 @implementation SplitDemoAppDelegate
4
5 @synthesize window=_window;
6
7 @synthesize downloadCache = _downloadCache;
8
9 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
10
11 {
12
13     //初始化ASIDownloadCache缓存对象
14
15    ASIDownloadCache *cache = [[ASIDownloadCache alloc] init];
16
17    self.downloadCache = cache;
18
19   [cache release];
20
21
22    //路径
23
24    NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
25
26   NSString *documentDirectory = [paths objectAtIndex:0];
27
28    //设置缓存存放路径
29
30    [self.downloadCache setStoragePath:[documentDirectorystringByAppendingPathComponent:@"resource"]];
31
32    //设置缓存策略
33
34     [self.downloadCache setDefaultCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];
35
36     // Override point for customization after application launch.
37
38     [self.window makeKeyAndVisible];
39
40     return YES;
41
42 }
43
44
45 - (void)dealloc
46
47 {
48
49     [_window release];
50
51     [_downloadCache release];
52
53    [super dealloc];
54
55 }
56
57 @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) SELresourceDidReceive;
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 @end


ResourceContainer.m文件实现:

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


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

三、图片请求(利用上面创建的类)
这里以我的工程为例进行分析:
在DetailViewController.h声明文件中:

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


在DetailViewController.m实现文件中:

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