在我们实际工程中,很多情况需要从 网络上加载 图片,然后将图片在imageview中 显示出来,但每次都要从网络上请求,会严重影响用户体验,为了不是每次显示都需要从网上 下载数据,希望将图片放到本地缓存,因此我们需要一个好的的缓存策略,今天我将我在项目工程中的实际经验分享给大家,我这里主要介绍一下强大的ASIHTTPRequest的缓存策略,以及使用方法:
下面是具体步骤:
一、设置缓存策略
首先在SplitDemoAppDelegate委托代理中,实现如下代码:
在SplitDemoAppDelegate.h文件中,代码如下:
#import <UIKit/UIKit.h> @class ASIDownloadCache; @interface SplitDemoAppDelegate : NSObject <UIApplicationDelegate,UITabBarControllerDelegate> { UIWindow *_window; ASIDownloadCache *_downloadCache; //下载缓存策略 } @property (nonatomic, retain) ASIDownloadCache *downloadCache; @end
#import "SplitDemoAppDelegate.h" @implementation SplitDemoAppDelegate @synthesize window=_window; @synthesize downloadCache = _downloadCache; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { //初始化ASIDownloadCache缓存对象 ASIDownloadCache *cache = [[ASIDownloadCache alloc] init]; self.downloadCache = cache; [cache release]; //路径 NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES); NSString *documentDirectory = [paths objectAtIndex:0]; //设置缓存存放路径 [self.downloadCache setStoragePath:[documentDirectorystringByAppendingPathComponent:@"resource"]]; //设置缓存策略 [self.downloadCache setDefaultCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy]; // Override point for customization after application launch. [self.window makeKeyAndVisible]; return YES; } - (void)dealloc { [_window release]; [_downloadCache release]; [super dealloc]; } @end
二、创建缓存线程
这一步是创建一个NSOperation类,实现缓存的方法,代码如下:
ResourceContainer.h文件实现:
#import <Foundation/Foundation.h> #import "ASIHTTPRequest.h" #import "SplitDemoAppDelegate.h" @interface ResourceContainer : NSOperation { NSURL *_resourceURL; //资源请求url NSObject *_hostObject; SEL _resourceDidReceive; //资源接手响应方法 SplitDemoAppDelegate *_appDelegate; //应用委托对象 ASIHTTPRequest *_httpRequest; UIImageView *_imageView; } @property (nonatomic, retain) NSURL *resourceURL; @property (nonatomic, retain) NSObject *hostObject; @property (nonatomic, assign) SEL resourceDidReceive; @property (nonatomic, assign) SplitDemoAppDelegate *appDelegate; @property (nonatomic, retain) ASIHTTPRequest *httpRequest; @property (nonatomic, retain) UIImageView *imageView; //http请求回调方法 -(void)didStartHttpRequest:(ASIHTTPRequest *)request; -(void)didFinishHttpRequest:(ASIHTTPRequest *)request; -(void)didFailedHttpRequest:(ASIHTTPRequest *)request; //取消资源请求 -(void)cancelReourceGet; //资源接收回调方法 -(void)resourceDidReceive:(NSData *)resource; @end
ResourceContainer.m文件实现:
#import "ResourceContainer.h" #import "HttpConstant.h" #import "ASIDownloadCache.h" @implementation ResourceContainer @synthesize resourceURL = _resourceURL; @synthesize hostObject = _hostObject; @synthesize resourceDidReceive = _resourceDidReceive; @synthesize appDelegate = _appDelegate; @synthesize httpRequest = _httpRequest; @synthesize imageView = _imageView; -(id)init{ if(self == [super init]){ self.appDelegate = (SplitDemoAppDelegate *)[[UIApplication sharedApplication] delegate]; } return self; } -(void)main{ if(self.hostObject == nil) return; if(self.resourceURL == nil){ [self resourceDidReceive:nil]; return; } ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:self.resourceURL]; self.httpRequest = request; [self.httpRequest setDownloadCache:self.appDelegate.downloadCache]; [self.httpRequest setDelegate:self]; [self.httpRequest setDidStartSelector:@selector(didStartHttpRequest:)]; [self.httpRequest setDidFinishSelector:@selector(didFinishHttpRequest:)]; [self.httpRequest setDidFailSelector:@selector(didFailedHttpRequest:)]; //发异步请求 [self.httpRequest startAsynchronous]; } - (void)dealloc { [_resourceURL release]; [_hostObject release]; [_httpRequest release]; [_imageView release]; [super dealloc]; } //开始请求 -(void)didStartHttpRequest:(ASIHTTPRequest *)request{ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; } //请求成功返回处理结果 -(void)didFinishHttpRequest:(ASIHTTPRequest *)request{ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; if([request responseStatusCode] == 200 || [request responseStatusCode] == 304){ //判断是否来自缓存 if([request didUseCachedResponse]){ NSLog(@"=========资源请求:%@ 来自缓存============",[self.resourceURL absoluteURL]); }else{ NSLog(@"=========资源请求:图片不来自缓存============"); } [self resourceDidReceive:[request responseData]]; }else { [self resourceDidReceive:nil]; } } //失败请求返回处理结果 -(void)didFailedHttpRequest:(ASIHTTPRequest *)request{ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; [self resourceDidReceive:nil]; } //取消资源请求 -(void)cancelReourceGet{ [self.httpRequest cancel]; } //资源接收处理方法 -(void)resourceDidReceive:(NSData *)resource{ if([self.hostObject respondsToSelector:self.resourceDidReceive]){ if(resource != nil && self.imageView != nil){ self.imageView.image = [UIImage imageWithData:resource]; } [self.hostObject performSelectorOnMainThread:self.resourceDidReceive withObject:self.imageViewwaitUntilDone:NO]; } } @end
三、图片请求(利用上面创建的类)
这里以我的工程为例进行分析:
在DetailViewController.h声明文件中,
#import <UIKit/UIKit.h> @interface DetailViewController :UIViewController { NSURL *_imageURL; //图片url NSMutableArray *_originalIndexArray; //保存请求图片的号 NSMutableDictionary *_originalOperationDic; //保存图片请求队列 NSOperationQueue *_requestImageQueue; //图片请求队列 } @property (nonatomic, retain) NSURL *imageURL; @property (nonatomic, retain) NSMutableArray *originalIndexArray; @property (nonatomic, retain) NSMutableDictionary *originalOperationDic; @property (nonatomic, retain) NSOperationQueue * requestImageQueue; //显示图片信息 -(void)displayProductImage; //根据图片序号显示请求图片资源 -(void)displayImageByIndex:(NSInteger)index ByImageURL:(NSURL *)url; //处理图片请求返回信息 -(void)imageDidReceive:(UIImageView *)imageView; @end
在DetailViewController.m实现文件中,
#import "ProductDetailViewController.h" //这里引入在第二步中,我们创建的对象 #import "ResourceContainer.h"
@implementation DetailViewController @synthesize imageURL = _imageURL; @synthesize originalIndexArray = _originalIndexArray; @synthesize originalOperationDic = _originalOperationDic; @synthesize requestImageQueue = _requestImageQueue;
- (void)viewDidLoad { [super viewDidLoad]; NSOperationQueue *tempQueue = [[NSOperationQueue alloc] init]; self.requsetImageQueue = tempQueue; [tempQueue release]; NSMutableArray *array = [[NSMutableArray alloc] init]; self.originalIndexArray = array; [array release]; NSMutableDictionary *dic = [[NSMutableDictionary alloc] init]; self.originalOperationDic = dic; [dic release]; } //显示图片信息 -(void)displayProductImage { NSURL *url = [NSURL URLWithString:@"http://xxx.xxx.xxx.xxx"]; //这个是从器返回有图片数目,self.xxxx根据具体的场合 int imageCount = [self.xxxx.imageNum intValue]; for (int i=0; i<imageCount; i++) { NSString *str1 = @"这里是拼图片请求url,根据实际需求"; self.imageURL = [url URLByAppendingPathComponent:str1]; //根据图片号请求资源 [self displayImageByIndex:i ByImageURL:self.productImageURL]; } } //根据图片序号显示请求图片资源 -(void) displayImageByIndex:(NSInteger)index ByImageURL:(NSURL *)url { NSString *indexForString = [NSString stringWithFormat:@"%d",index]; //若数组中已经存在该图片编号,说明图片加载完毕,直接返回 if ([self.originalIndexArray containsObject:indexForString]) { return; } //创建UIImageView对象 UIImageView *imageView = [[UIImageView alloc] init]; imageView.tag = index; //创建资源请求对象 ResourceContainer *imageOperation = [[ResourceContainer alloc] init]; imageOperation.resourceURL = url; imageOperation.hostObject = self; //设置收到图片信息处理理方法 imageOperation.resourceDidReceive = @selector(imageDidReceive:); imageOperation.imageView = imageView; [imageView release]; //将图片请求对象加入图片请求队列中 [self.requsetImageQueue addOperation:imageOperation]; [self.originalOperationDic setObject:imageOperation forKey:indexForString]; [imageOperation release]; } //处理图片请求返回信息 -(void)imageDidReceive:(UIImageView *)imageView { if (imageView == nil||imageView.image == nil) { imageView.image = [UIImage imageNamed:@"no-pic-300-250.png"]; } //将图片信息加载到前台,self.openFlowView是我用的coverFlow,coverFlow的使用方法网上很多,自己找吧 [self.openFlowView setImage:imageView.image forIndex:imageView.tag]; [self.originalIndexArray addObject:[NSString stringWithFormat:@"%d",imageView.tag]]; [self.originalOperationDic removeObjectForKey:[NSString stringWithFormat:@"%d",imageView.tag]]; } - (void)dealloc { [_requestImageQueue release]; [_originalIndexArray release]; [_originalOperationDic release]; [_imageURL release]; [super dealloc]; } @end
文章转载自:http://blog.csdn.net/pjk1129/article/details/6574280