下载图片缓存方法
2014-01-05 09:29
260 查看
在我们实际工程中,很多情况需要从网络上加载图片,然后将图片在imageview中显示出来,但每次都要从网络上请求,会严重影响用户体验,为了不是每次显示都需要从网上下载数据,希望将图片放到本地缓存,因此我们需要一个好的的缓存策略,今天我将我在项目工程中的实际经验分享给大家,我这里主要介绍一下强大的ASIHTTPRequest的缓存策略,以及使用方法:
下面是具体步骤:
一、设置缓存策略
首先在SplitDemoAppDelegate委托代理中,实现如下代码:
在SplitDemoAppDelegate.h文件中,代码如下:
在SplitDemoAppDelegate.m文件中,代码如下:
二、创建缓存线程
这一步是创建一个NSOperation类,实现缓存的方法,代码如下:
ResourceContainer.h文件实现:
ResourceContainer.m文件实现:
到第二步,我们的缓存策略的设置,以及资源请求和接收数据方法已经构建完毕,下面介绍一下如何使用我们上面创建的NSOperation类
三、图片请求(利用上面创建的类)
这里以我的工程为例进行分析:
在DetailViewController.h声明文件中:
在DetailViewController.m实现文件中:
下面是具体步骤:
一、设置缓存策略
首先在SplitDemoAppDelegate委托代理中,实现如下代码:
在SplitDemoAppDelegate.h文件中,代码如下:
#import <UIKit/UIKit.h> @class ASIDownloadCache; @interface SplitDemoAppDelegate : NSObject <UIApplicationDelegate,UITabBarControllerDelegate> { UIWindow *_window; ASIDownloadCache*_downloadCache; //下载缓存策略 } @property (nonatomic, retain) ASIDownloadCache*downloadCache; @end
在SplitDemoAppDelegate.m文件中,代码如下:
#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) SELresourceDidReceive; @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
到第二步,我们的缓存策略的设置,以及资源请求和接收数据方法已经构建完毕,下面介绍一下如何使用我们上面创建的NSOperation类
三、图片请求(利用上面创建的类)
这里以我的工程为例进行分析:
在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
相关文章推荐
- 图片下载本地缓存时间戳显示图片方法
- 图片下载缓存库Picasso清除缓存方法
- php获取远程图片并下载保存到本地的方法分析
- PHP根据图片url下载图片到本地的两种方法
- Pinterest开源图片下载和缓存框架--PINRemoteImage
- Android异步下载图片并且缓存图片到本地
- Django中实现点击图片链接强制直接下载的方法
- 图片下载缓存处理基础篇
- dede不能下载远程图片及如何实现图片本地化的方法
- Android中获取网络图片的方法(如果手机缓存里面有就从缓存获取)
- 从网络下载的图片加缓存功能
- OkHttp学习(2)-->>异步下载图片、文件(拦截器重写Response方法实现下载进度获取)
- android下载网络图片并缓存
- 安卓中关于图片从网络获取,压缩,上传,下载,缩略图,缓存的一些处理总结(二)
- iOS基础8:自定义MyData/自定义SQLite用于网络判断,版本判断,图片缓存处理,下载或者上传的GET或POST请求,加密手段,.数据解析
- php下载远程图片方法总结(curl手动解析header)curl跳转问题解决
- 微信小程序使用image组件显示图片的方法【附源码下载】
- ios 图片的网络下载和显示(可缓存)