iOS网络加载图片缓存策略之ASIDownloadCache缓存优化
在我们实际工程中,很多情况需要从网络上加载图片,然后将图片在imageview中显示出来,但每次都要从网络上请求,会严重影响用户体验,为了不是每次显示都需要从网上下载数据,希望将图片放到本地缓存,因此我们需要一个好的的缓存策略,今天我将我在项目工程中的实际经验分享给大家,我这里主要介绍一下强大的ASIHTTPRequest的缓存策略,以及使用方法。
AD:
在我们实际工程中,很多情况需要从网络上加载图片,然后将图片在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
在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
经过上述步骤,我们实现了加载网络图片时缓存功能,增强了用户体验效果。代码中可能会有诸多问题,希望网友指教,有更好的缓存方法,也希望一起交流!
经验总结。本书共17章,
iOS网络加载图片缓存策略之ASIDownloadCache缓存优化的更多相关文章
- iOS网络加载图片缓存与SDWebImage
加载网络图片可以说是网络应用中必备的.如果单纯的去下载图片,而不去做多线程.缓存等技术去优化,加载图片时的效果与用户体验就会很差. 一.自己实现加载图片的方法 tips: *iOS中所有网络访问都是异 ...
- android 网络加载图片,对图片资源进行优化,并且实现内存双缓存 + 磁盘缓存
经常会用到 网络文件 比如查看大图片数据 资源优化的问题,当然用开源的项目 Android-Universal-Image-Loader 或者 ignition 都是个很好的选择. 在这里把原来 ...
- Android加载图片的策略
实现图片缓存也不难,需要有相应的cache策略.这里我采用 内存-文件-网络 三层cache机制,其中内存缓存包括强引用缓存和软引用缓存(SoftReference),其实网络不算cache,这里姑且 ...
- 【转】Android循环滚动广告条的完美实现,封装方便,平滑过渡,从网络加载图片,点击广告进入对应网址
Android循环滚动广告条的完美实现,封装方便,平滑过渡,从网络加载图片,点击广告进入对应网址 关注finddreams,一起分享,一起进步: http://blog.csdn.net/finddr ...
- swift 基础小结01 --delegate、Optional、GCD的使用、request请求、网络加载图片并保存到沙箱、闭包以及桥接
本文主要记录swift中delegate的使用.“?!”Optional的概念.GCD的使用.request请求.网络加载图片并保存到沙箱.闭包以及桥接. 一.delegate的使用 swift中de ...
- ios -网络加载json和本地加载json
1网络加载json的时候,要在模型的实现文件里写: - (void)setValue:(id)value forKey:(NSString *)key { } 2本地加载json的时候,要在模型的实现 ...
- LruCache:从网络加载图片缓存实例
OOM异常 堆内存用于存储实例对象,当程序不断创建对象,并且对象都有引用指向,那么垃圾回收机制就不会清理这些对象,当对象多到挤满堆内存的上限后,就产生OOM异常.Android系统为每个应用程序使用的 ...
- 关于ios异步加载图片的几个开源项目
一.HjCache 原文:http://www.markj.net/hjcache-iphone-image-cache/ 获取 HJCache: HJCache is up on github h ...
- 使用自定义的item、Adapter和AsyncTask、第三方开源框架PullToRefresh联合使用实现自定义的下拉列表(从网络加载图片显示在item中的ImageView)
AsyncTask使用方法详情:http://www.cnblogs.com/zzw1994/p/4959949.html 下拉开源框架PullToRefresh使用方法和下载详情:http://ww ...
随机推荐
- Android——AnimationDrawable 实现动画
Android中的AnimationDrawable可以加载Drawable资源实现帧动画.实现步骤如下: 一.设置动画播放的帧资源 <?xml version="1.0" ...
- git的一些命令
因为项目的原因,大家把项目托管到git上,然后我不会,队友就传了一个廖雪峰的git教程,讲的很详细,不会用git的同学,可以在http://pan.baidu.com/s/1pKizolP上下载,这是 ...
- go can't find import: "github.com/** 错误
go get 后 go build 错误 can't find import: "github.com/ 原因: 1.gopath 没配好 2.go get 后要先 go install , ...
- 【手把手教你Elmah】如何在MVC.NET项目中在线查看【错误日志】
一. 在NuGet下载Elmah.MVC dll文件! 或者点击下载dll文件,并且引用客户端. 二.配置WebConfig <sectionGroup name="elmah& ...
- vb6如何将MSHFlexGrid控件中的内容导出为Excel
首先的是是准备工作 需要引用 Microsoft Excel 11.0 Object Library 需要添加控件Mircrosoft Hierarchical FlexGrid Control 6. ...
- Visual Studio 扩展包(.vsix)制作
前言:上篇介绍了 Visual Studio扩展工具添加与卸载,本编要介绍的是Visual Studio 扩展包(.vsix)的制作. 方法: ①.下载并安装Visual Studio 2010 SD ...
- 转:eclipse技巧之快速生成Override函数
转自: http://www.cnblogs.com/junqilian/archive/2013/03/15/2960277.html 小提示:Eclipse 中快速实现或Override基类或接口 ...
- 转: ImageMagick 命令行的图片处理工具(客户端与服务器均可用)
http://www.imagemagick.com.cn/ 关于ImageMagick ImageMagick (TM) 是一个免费的创建.编辑.合成图片的软件.它可以读取.转换.写入多种格式的图片 ...
- oc中的分类/协议/属性
1.分类:当我们想给某个类加一些方法时,如果不想通过继承这个类来实现,可以通过分类给这个类加一些行为,这个过程与继承相比更加轻量化. @interface NSString (SubClass) -( ...
- Angularjs 中使用指令绑定点击事件
项目中,模板中的菜单是jQuery控制的,在Angularjs中就运行不到了,因为菜单项是ng-repeat之后的. 如html <ul id="main-menu"> ...