文档章节

IOS开发之异步加载网络图片并缓存本地实现瀑布流(二)

Align
 Align
发布于 2016/01/05 14:56
字数 1276
阅读 65
收藏 1

在上一篇博客中,我们实现了异步加载图片的功能,由于上次的时间问题,讲的比较简单所以在这篇文章中,我对前面代码中涉及到得关键代码再做一次详细的解释。

先看一个函数,

[objc] view plaincopy在CODE上查看代码片派生到我的代码片

  1. /* 

  2.  * @brief 图片加载通用函数 

  3.  * @parma imageName 图片名 

  4.  */  

  5. - (void)imageStartLoading:(NSString *)imageName{  

  6.     NSURL *url = [NSURL URLWithString:imageName];  

  7.     if([_fileUtil hasCachedImage:url]){  

  8.         UIImageView *imageView = [[UIImageView alloc] init];  

  9.         NSString *path = [_fileUtil pathForUrl:url];  

  10.         imageView = [_imageLoad compressImage:MY_WIDTH/3 imageView:nil imageName:path flag:NO];  

  11.         [self addImage:imageView name:path];  

  12.         [self adjustContentSize:NO];  

  13.     }else{  

  14.         UIImageView *imageView = [[UIImageView alloc] init];  

  15.         NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:url, @"URL",  

  16.                              imageView, @"imageView", nil nil];  

  17.         [NSThread detachNewThreadSelector:@selector(cacheImage:) toTarget:[ImageCacher shareInstance] withObject:dic];  

  18.     }  

  19. }  


这个函数的作用是为每一张网络图片开启一个下载线程,但是因为该程序用到了图片缓存的技术,所以在每次开线程下载图片的时候都会去本地缓存目录查找一下,

该图片是否已经存在,如果存在则直接加载在视图中。一般OC的线程函数有三个,NSThread, Cocoa Operations,和GCD,(想要了解三者的异同点可查看:点击打开链接),

这里我用了比较轻量级的NSThread,detachNewThreadSelector函数中所传的函数名:cacheImage是类ImageCache中得函数,这里通过iOS开发中使用的比较多的单例模式,

得到了ImageCache的句柄,参数dic中主要存放了图片的网络地址以及imageView用来add图片进视图以及根据图片的大小压缩成合适的大小.


接下来是cacheImage函数:

[objc] view plaincopy在CODE上查看代码片派生到我的代码片

  1. - (void)cacheImage:(NSDictionary*)dic{  

  2.     NSURL *url = [dic objectForKey:@"URL"];  

  3.     NSFileManager *fileManage = [NSFileManager defaultManager];  

  4.     NSData *data = [NSData dataWithContentsOfURL:url];  

  5.       

  6.     NSString *fileName = [_fileUtil pathForUrl:url];  

  7.     if(data){  

  8.         [fileManage createFileAtPath:fileName contents:data attributes:nil];  

  9.     }  

  10.       

  11.     UIImageView *imageView = [dic objectForKey:@"imageView"];  

  12.     imageView.image = [UIImage imageWithData:data];  

  13.     imageView = [_imageLoader compressImage:MY_WIDTH/3 imageView:imageView imageName:nil flag:YES];  

  14.     [self.myDelegate addImage:imageView name:fileName];  

  15.     [self.myDelegate adjustContentSize:NO];  

  16. }  


该函数用来将下载下来的图片缓存进入文件沙盒中(缓存文件可以自己定义并指定),并且按照图片的大小进行等比例压缩,固定宽度是屏幕的三分之一大小,这样一来,

图片显示就不会出现不全或失真的现象。由于ImageCache和MyScrollView是两个独立的类,所以这里通过使用ios的delegate(代理)来进行图片在scrollView上的加载,

(什么是代理模式:点击打开链接).


下面我们来看如何在沙盒中建立缓存文件夹,其实缓存文件夹跟普通的文件夹一样,只是该文件夹是专门用来存放缓存文件的而已。类代码如下所示:

[objc] view plaincopy在CODE上查看代码片派生到我的代码片

  1. //  

  2. //  FileUtil.m  

  3. //  Test515  

  4. //  

  5. //  Created by silicon on 14-5-30.  

  6. //  Copyright (c) 2014年 silicon. All rights reserved.  

  7. //  

  8.   

  9. #import "FileUtil.h"  

  10.   

  11. @implementation FileUtil  

  12.   

  13. + (FileUtil *)shareInstance{  

  14.     static FileUtil *instance;  

  15.     static dispatch_once_t onceToken;  

  16.     dispatch_once(&onceToken, ^{  

  17.         instance = [[self alloc] init];  

  18.     });  

  19.       

  20.     return instance;  

  21. }  

  22.   

  23. /* 

  24.  @breif 创建缓存文件夹 

  25.  */  

  26. - (void)createPathInDocumentDirectory{  

  27.     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);  

  28.     NSString *diskCachePath = [[[paths objectAtIndex:0] stringByAppendingPathComponent:@"ImageCache"] retain];  

  29.     NSLog(@"%@", diskCachePath);  

  30.       

  31.     if(![[NSFileManager defaultManager] fileExistsAtPath:diskCachePath]){  

  32.         NSError *error = nil;  

  33.         [[NSFileManager defaultManager] createDirectoryAtPath:diskCachePath  

  34.                                   withIntermediateDirectories:YES  

  35.                                                    attributes:nil  

  36.                                                         error:&error];  

  37.     }  

  38. }  

  39.   

  40. /* 

  41.  @breif     获取沙盒中文档目录 

  42.  @param     fileName:文件名字 

  43.  */  

  44. - (NSString *)pathInDocumentDirectory:(NSString *)fileName{  

  45.     NSArray *fileArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,  

  46.                                                              NSUserDomainMask, YES);  

  47.     NSString *cacheDirectory = [fileArray objectAtIndex:0];  

  48.     return [cacheDirectory stringByAppendingPathComponent:fileName];  

  49. }  

  50.   

  51. /* 

  52.  @breif     获取沙盒中缓存文件目录 

  53.  @param     fileName:文件名字 

  54.  */  

  55. - (NSString *)pathInCacheDirectory:(NSString *)fileName{  

  56.     NSArray *fileArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,  

  57.                                                              NSUserDomainMask, YES);  

  58.     NSString *cacheDirectory = [fileArray objectAtIndex:0];  

  59.     return [cacheDirectory stringByAppendingPathComponent:fileName];  

  60. }  

  61.   

  62. /* 

  63.  @breif     判断是否已经缓存 

  64.  @param     url:图片名称 

  65.  */  

  66. - (BOOL)hasCachedImage:(NSURL *)url{  

  67.     NSFileManager *fileManager = [NSFileManager defaultManager];  

  68.     if([fileManager fileExistsAtPath:[self pathForUrl:url]]){  

  69.         return YES;  

  70.     }else{  

  71.         return NO;  

  72.     }  

  73. }  

  74.   

  75. /* 

  76.  @breif     根据URL的給图片命名 

  77.  @param     url:图片url 

  78.  */  

  79. - (NSString *)pathForUrl:(NSURL *)url{  

  80.     return [self pathInCacheDirectory:[NSString stringWithFormat:@"qiaoqiao-%u", [[url description] hash]]];  

  81. }  

  82.   

  83. @end  


在这次的demo中,我新加入了用户可以点击图片放大 并可以左右滑动的功能,其实实现起来很简单,我一开始为每一个ScrollView 中得ImageView都设置了tag值,并且添加了

手势(UITapGestureRecognizer),当用户点击图片时,程序可以根据点击视图的tag值来获得相应的图片是哪一张,从而可以加载。支持左右滑动的功能在新的界面中增加了

一个ScrollView,然后将下载下来的图片添加到scrollView中。代码如下

[objc] view plaincopy在CODE上查看代码片派生到我的代码片

  1. //  

  2. //  PhotoViewController.m  

  3. //  Test515  

  4. //  

  5. //  Created by silicon on 14-5-22.  

  6. //  Copyright (c) 2014年 silicon. All rights reserved.  

  7. //  

  8.   

  9. #import "PhotoViewController.h"  

  10. #import "ImageLoader.h"  

  11.   

  12. @interface PhotoViewController ()  

  13.   

  14. @end  

  15.   

  16. @implementation PhotoViewController  

  17. @synthesize scrollView = _scrollView;  

  18. @synthesize imageArray = _imageArray;  

  19. @synthesize page = _page;  

  20.   

  21. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  

  22. {  

  23.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  

  24.     if (self) {  

  25.         // Custom initialization  

  26.     }  

  27.     return self;  

  28. }  

  29.   

  30. - (void)viewDidLoad  

  31. {  

  32.     [super viewDidLoad];  

  33.     // Do any additional setup after loading the view.  

  34.     [self.view setFrame:CGRectMake(0, 0, MY_WIDTH, MY_HEIGHT)];  

  35.     [self.view setBackgroundColor:[UIColor blackColor]];  

  36.       

  37.     self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 20, MY_WIDTH, MY_HEIGHT)];  

  38.     _scrollView.delegate = self;  

  39.     _scrollView.contentSize = CGSizeMake(MY_WIDTH * [_imageArray count], MY_HEIGHT);  

  40.     _scrollView.showsVerticalScrollIndicator = NO;  

  41.     _scrollView.showsHorizontalScrollIndicator = NO;  

  42.     _scrollView.backgroundColor = [UIColor blackColor];  

  43.     _scrollView.bounces = YES;  

  44.     _scrollView.pagingEnabled = YES;  

  45.     [self.view addSubview:_scrollView];  

  46.       

  47.     //图片添加事件响应  

  48.     UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(closePhotoView)];  

  49.     tapRecognizer.delegate = self;  

  50.     _scrollView.userInteractionEnabled = YES;  

  51.     [_scrollView addGestureRecognizer:tapRecognizer];  

  52.     [tapRecognizer release];  

  53.       

  54.     [self loadingImages];  

  55. }  

  56.   

  57. - (void)viewWillAppear:(BOOL)animated{  

  58.     [_scrollView setContentOffset:CGPointMake([_imageArray indexOfObject:_imageName] * MY_WIDTH, 0)];  

  59. }  

  60.   

  61. - (void)didReceiveMemoryWarning  

  62. {  

  63.     [super didReceiveMemoryWarning];  

  64.     // Dispose of any resources that can be recreated.  

  65. }  

  66.   

  67. //关闭  

  68. - (void)closePhotoView{  

  69.     [self.view removeFromSuperview];  

  70. }  

  71.   

  72. - (void)dealloc{  

  73.     [_scrollView release];  

  74.     [super dealloc];  

  75. }  

  76.   

  77. - (void)loadingImages{  

  78.     //加载图片  

  79.     for(int i = 0; i < [_imageArray count]; i++){  

  80.         NSString *picName = [_imageArray objectAtIndex:i];  

  81.         UIImageView *imageV = [[ImageLoader shareInstance] compressImage:MY_WIDTH imageView:nil imageName:picName flag:NO];  

  82.           

  83.         float width = imageV.image.size.width;  

  84.         float height = imageV.image.size.height;  

  85.           

  86.         float new_width = MY_WIDTH;  

  87.         float new_height = (MY_WIDTH * height)/width;  

  88.           

  89.         imageV.frame = CGRectMake(MY_WIDTH * i, 0, new_width, new_height);  

  90.         [_scrollView addSubview:imageV];  

  91.         [imageV release];  

  92.     }  

  93. }  

  94.   

  95. - (void)scrollViewDidScroll:(UIScrollView *)_scrollView{  

  96.   

  97. }  

  98.   

  99. @end  



© 著作权归作者所有

Align
粉丝 11
博文 65
码字总数 71695
作品 0
昌平
高级程序员
私信 提问
iOS开发swift版异步加载网络图片(带缓存和缺省图片)

iOS开发之swift版异步加载网络图片 与SDWebImage异步加载网络图片的功能相似,只是代码比较简单,功能没有SD的完善与强大,支持缺省添加图片,支持本地缓存。 异步加载图片的核心代码如下: ...

珲少
2015/06/25
0
2
(转)直接拿来用!最火的iOS开源项目(二)

“每一次的改变总意味着新的开始。”这句话用在iOS上可谓是再合适不过的了。GitHub上的iOS开源项目数不胜数,iOS每一次的改变,总会引发iOS开源项目的演变,从iOS 1.x到如今的iOS 7,有的项目...

孙启超
2013/06/21
0
1
Java转iOS-第一个项目总结(1)

0.前言 本人14年12月份,从网站开发组转到了移动开发组,自己的java两年半工作经验变成了objective-c零经验。2015年1月份新启动了一个移动项目,年后因为人事变动,自己从辅助开发变成了"核心...

蛙牛
2015/03/31
0
67
WebView自动缓存-清除缓存

iOS的Webview加载HTML时会自动缓存JS、CSS等文件,当下次加载HTML时会根据请求的缓存策略是否使用缓存本地的JS和CSS,如果本地有缓存,那么直接返回本地资源(判断是否过期);如果没有本地缓存...

一誠
04/13
0
0
OSChina 技术专题之 Swift 苹果全新开发语言

Swift 是苹果新推出的编程语言,专门针对 OS X 和 iOS 的应用开发。Swift 在各个方面优于 Objective-C,也不会有那么多复杂的符号和表达式。同时,Swift 更加快速、便利、高效、安全。除此之...

OSC编辑部
2014/11/10
4.2K
4

没有更多内容

加载失败,请刷新页面

加载更多

定时获取服务器时间戳的一个类(Typescript)

export class TimeStampService { private _local_timestamp: number; // 本地时间戳 private _server_timestamp: number; // 服务器端时间戳 private _duration: number = 1......

lilugirl
18分钟前
0
0
前段技术总结

前端UI框架组件库: 说到前端框架我第一印象中想起React、Vue和Angular,不知道你是否与我一样想到这些,现在常用的有:Bootstrap、jQuery UI、BootMetro、AUI常用的还有很多、就不一一跟大家...

WinkJie
38分钟前
0
0
对话亲历者|鲁肃:我在支付宝“拧螺丝“的日子

摘要: 他是支付宝技术平台的奠基人之一,但是他总说“这还不是我心中最完美的架构”;他行事低调但却有着“此时此地,非我莫属”的豪气;他曾无数次充当救火大队长,但自评只是“没有掉队的...

阿里云云栖社区
45分钟前
4
0
设置 npm yarn 淘宝源

设置npm config set chromedriver_cdnurl=http://cdn.npm.taobao.org/dist/chromedriver设置yarn config set "chromedriver_cdnurl" "https://npm.taobao.org/mirrors/chromedriver"......

internetafei
54分钟前
2
0
Docker搭建Mysql集群、主从同步复制

1、创建数据挂载点: mkdir /opt/mysql-master/mysql、/opt/mysql-master/conf.d、/opt/mysql-slave/mysql、/opt/mysql-slave/conf.d 2、分别在master、slave节点文件目录conf.d下创建touch......

WALK_MAN
今天
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部