IOS开发中加载大量网络图片如何优化
1、概述
在IOS下通过URL读一张网络图片并不像其他编程语言那样可以直接把图片路径放到图片路径的位置就ok,而是需要我们通过一段类似流的方式去加载网络图片,接着才能把图片放入图片路径显示。比如:
-(UIImage *) getImageFromURL:(NSString *)fileURL { //NSLog(@"执行图片下载函数"); UIImage * result; NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]]; result = [UIImage imageWithData:data]; return result; }
加载网络图片可以说是网络应用中必备的。如果单纯的去下载图片,而不去做多线程、缓存等技术去优化,加载图片时的效果与用户体验就会很差。
优化思路为:
(1)本地缓存
(2)异步加载
(3)加载完毕前使用占位图片
2、优化方法
方法1:用NSOperation开异步线程下载图片,当下载完成时替换占位图片
#import "XNViewController.h" #import "XNApp.h" @interface XNViewController () @property (nonatomic, strong) NSArray *appList; @property (nonatomic, strong) NSOperationQueue *queue; @end @implementation XNViewController #pragma mark - 懒加载 - (NSOperationQueue *)queue { if (!_queue) _queue = [[NSOperationQueue alloc] init]; return _queue; } //可抽取出来写到模型中 - (NSArray *)appList { if (!_appList) { //1.加载plist到数组中 NSURL *url = [[NSBundle mainBundle] URLForResource:@"apps.plist" withExtension:nil]; NSArray *array = [NSArray arrayWithContentsOfURL:url]; //2.遍历数组 NSMutableArray *arrayM = [NSMutableArray array]; [array enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) { [arrayM addObject:[XNApp appWithDict:obj]]; //数组中存放的是字典, 转换为app对象后再添加到数组 }]; _appList = [arrayM copy]; } return _appList; } - (void)viewDidLoad { [super viewDidLoad]; self.tableView.rowHeight = 88; // NSLog(@"appList-%@",_appList); } #pragma mark - 数据源方法 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.appList.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *ID = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; //用模型来填充每个cell XNApp *app = self.appList[indexPath.row]; cell.textLabel.text = app.name; //设置文字 //设置图像: 模型中图像为nil时用默认图像,并下载图像. 否则用模型中的内存缓存图像. if (!app.image) { cell.imageView.image = [UIImage imageNamed:@"user_default"]; [self downloadImg:indexPath]; } else { //直接用模型中的内存缓存 cell.imageView.image = app.image; } // NSLog(@"cell--%p", cell); return cell; } /**始终记住, 通过模型来修改显示. 而不要试图直接修改显示*/ - (void)downloadImg:(NSIndexPath *)indexPath { XNApp *app = self.appList[indexPath.row]; //取得改行对应的模型 [self.queue addOperationWithBlock: ^{ NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]]; //得到图像数据 UIImage *image = [UIImage imageWithData:imgData]; //在主线程中更新UI [[NSOperationQueue mainQueue] addOperationWithBlock: ^{ //通过修改模型, 来修改数据 app.image = image; //刷新指定表格行 [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; }]; }]; } @end
上述代码只是做了内存缓存,还没有做本地缓存,因为这里这种方法不是重点,也不是首选方法。上面代码每次重新进入应用时,还会从网上重新下载。如果要继续优化上面的代码,需要自己去实现本地缓存。
方法2:使用第三方框架SDWebImage
特点:
依赖的库很少,功能全面。
自动实现磁盘缓存:缓存图片名字是以MD5进行加密的后的名字进行命名.(因为加密那堆字串是唯一的)
加载网络图片时直接设置占位图片:[imageView sd_setImageWithURL:imageurl placeholderImage:[UIImage imageNamed:@”xxxxx”]]。
就一个方法就实现了多线程\带缓冲等效果.(可用带参数的方法,具体可看头文件)
用SDWebImage修改上面的方法后的代码可简化为:
#pragma mark - 数据源方法 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.appList.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *ID = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; //用模型来填充每个cell XNApp *app = self.appList[indexPath.row]; cell.textLabel.text = app.name; //设置文字 // //设置图像: 模型中图像为nil时用默认图像,并下载图像. 否则用模型中的内存缓存图像. // if (!cell.imageView.image) { // cell.imageView.image = [UIImage imageNamed:@"user_default"]; // // [self downloadImg:indexPath]; // } // else { // //直接用模型中的内存缓存 // cell.imageView.image = app.image; // } //使用SDWebImage来完成上面的功能. 针对ImageView. //一句话, 自动实现了异步下载. 图片本地缓存. 网络下载. 自动设置占位符. [cell.imageView sd_setImageWithURL:[NSURL URLWithString:app.icon] placeholderImage:[UIImage imageNamed:@"user_default"]]; return cell; } /**始终记住, 通过模型来修改显示. 而不要试图直接修改显示*/ //- (void)downloadImg:(NSIndexPath *)indexPath { // XNApp *app = self.appList[indexPath.row]; //取得改行对应的模型 // // [self.queue addOperationWithBlock: ^{ // NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]]; //得到图像数据 // UIImage *image = [UIImage imageWithData:imgData]; // // //在主线程中更新UI // [[NSOperationQueue mainQueue] addOperationWithBlock: ^{ // //通过修改模型, 来修改数据 // app.image = image; // //刷新指定表格行 // [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; // }]; // }]; //} @end
【备注】SDWebImage中的一些参数:
*SDWebImageRetryFailed = 1<< 0, 默认选项,失败后重试 *SDWebImageLowPriority = 1<< 1, 使用低优先级 *SDWebImageCacheMemoryOnly = 1<< 2, 仅仅使用内存缓存 *SDWebImageProgressiveDownload = 1<< 3, 显示现在进度 *SDWebImageRefreshCached = 1<< 4, 刷新缓存 *SDWebImageContinueInBackground =1 << 5, 后台继续下载图像 *SDWebImageHandleCookies = 1<< 6, 处理Cookie *SDWebImageAllowInvalidSSLCertificates= 1 << 7, 允许无效的SSL验证 *SDWebImageHighPriority = 1<< 8, 高优先级 *SDWebImageDelayPlaceholder = 1<< 9 延迟显示占位图片
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
本文向大家介绍IOS 开发之网络图片轮播图的实现,包括了IOS 开发之网络图片轮播图的实现的使用技巧和注意事项,需要的朋友参考一下 IOS 开发之网络图片轮播图的实现 截图 1.使用 2.源码 如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
本文向大家介绍网站首页有大量的图片,加载很慢,要是你,你该怎么去优化呢?相关面试题,主要包含被问及网站首页有大量的图片,加载很慢,要是你,你该怎么去优化呢?时的应答技巧和注意事项,需要的朋友参考一下 问题不同解决的方法也不同 1,启动页面时加载过多的图片 使用瀑布流==》懒加载 使用雪碧图==〉多个小图放在一个大图上 使用骨架图 首屏优先加载 2,部分图片体积过大 一张100px100px的图片,
本文向大家介绍在Android的应用中实现网络图片异步加载的方法,包括了在Android的应用中实现网络图片异步加载的方法的使用技巧和注意事项,需要的朋友参考一下 前言 其实很幸运,入职一周之后就能跟着两个师兄做android开发,师兄都是大神,身为小白的我只能多多学习,多多努力。最近一段时间都忙的没机会总结,今天刚完成了android客户端图片异步加载的类,这里记录一下(ps:其实我这里都是参考
本文向大家介绍Android实现网络加载图片点击大图后浏览可缩放,包括了Android实现网络加载图片点击大图后浏览可缩放的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Android九宫格图片展示的具体代码,供大家参考,具体内容如下 找了一些demo感觉没有自己想要的效果,于是借鉴一些改造一下并记录下来; 1、主Activity 2、显示图片的GalleryAdapter 3、自定
本文向大家介绍Afianl框架里面的FinalBitmap加载网络图片,包括了Afianl框架里面的FinalBitmap加载网络图片的使用技巧和注意事项,需要的朋友参考一下 Afinal里面FinalBitmap:用于显示bitmap图片,而无需考虑线程并发和oom等问题。 1.测试请求 使用网页打开http://avatar.csdn.net/C/6/8/1_bz419927089.jpg
本文向大家介绍iOS开发网络篇—实现大文件的多线程断点下载,包括了iOS开发网络篇—实现大文件的多线程断点下载的使用技巧和注意事项,需要的朋友参考一下 说明:本文介绍多线程断点下载。项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件。因为实现过程较为复杂,所以下面贴出完整的代码。 实现思路:下载开始,创建一个和要下载的文件大小相同的文件(如果要下载的文件为100M,那么就在沙盒中创