iOS网络加载图片缓存与SDWebImage

简介: 加载网络图片可以说是网络应用中必备的。如果单纯的去下载图片,而不去做多线程、缓存等技术去优化,加载图片时的效果与用户体验就会很差。 一、自己实现加载图片的方法 tips:   *iOS中所有网络访问都是异步的.(自己开线程去下载) *普通为模型增加UIImage属性的方法做的是内存缓存(下次启动还需要从网络重新加载), 而要做本地缓存的话,还要自己手动存储网络上下载的图片. *为了加快访问, 还需要自己去弄缓存.(内存缓存或者本地缓存) *当图片没有下载完成时,还要设置占位图片。

加载网络图片可以说是网络应用中必备的。如果单纯的去下载图片,而不去做多线程、缓存等技术去优化,加载图片时的效果与用户体验就会很差。

一、自己实现加载图片的方法

tips:

 

*iOS中所有网络访问都是异步的.(自己开线程去下载) *普通为模型增加UIImage属性的方法做的是内存缓存(下次启动还需要从网络重新加载), 而要做本地缓存的话,还要自己手动存储网络上下载的图片. *为了加快访问, 还需要自己去弄缓存.(内存缓存或者本地缓存) *当图片没有下载完成时,还要设置占位图片。

 

以下代码用NSOperation开异步线程下载图片,当下载完成时替换占位图片。

 

01. //
02. //  XNViewController.m
03. //  加载网络图片, 普通的用NSOperation来做.
04. //
05. //  Created by neng on 14-7-7.
06. //  Copyright (c) 2014年 neng. All rights reserved.
07. //
08.  
09. #import "XNViewController.h"
10. #import "XNApp.h"
11.  
12. @interface XNViewController ()
13. @property (nonatomic, strong) NSArray *appList;
14. @property (nonatomic, strong) NSOperationQueue *queue;
15. @end
16.  
17. @implementation XNViewController
18. #pragma mark - 懒加载
19.  
20. - (NSOperationQueue *)queue {
21. if (!_queue) _queue = [[NSOperationQueue alloc] init];
22. return _queue;
23. }
24.  
25. //可抽取出来写到模型中
26. - (NSArray *)appList {
27. if (!_appList) {
28. //1.加载plist到数组中
29. NSURL *url = [[NSBundle mainBundle] URLForResource:@"apps.plist" withExtension:nil];
30. NSArray *array = [NSArray arrayWithContentsOfURL:url];
31. //2.遍历数组
32. NSMutableArray *arrayM = [NSMutableArray array];
33. [array enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) {
34. [arrayM addObject:[XNApp appWithDict:obj]];  //数组中存放的是字典, 转换为app对象后再添加到数组
35. }];
36. _appList = [arrayM copy];
37. }
38. return _appList;
39. }
40.  
41. - (void)viewDidLoad {
42. [super viewDidLoad];
43.  
44. self.tableView.rowHeight = 88;
45.  
46. //    NSLog(@"appList-%@",_appList);
47. }
48.  
49. #pragma mark - 数据源方法
50. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
51. return self.appList.count;
52. }
53.  
54. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
55. static NSString *ID = @"Cell";
56. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
57.  
58. //用模型来填充每个cell
59. XNApp *app = self.appList[indexPath.row];
60. cell.textLabel.text = app.name;  //设置文字
61.  
62. //设置图像: 模型中图像为nil时用默认图像,并下载图像. 否则用模型中的内存缓存图像.
63. if (!app.image) {
64. cell.imageView.image = [UIImage imageNamed:@"user_default"];
65.  
66. [self downloadImg:indexPath];
67. }
68. else {
69. //直接用模型中的内存缓存
70. cell.imageView.image = app.image;
71. }
72. //  NSLog(@"cell--%p", cell);
73.  
74. return cell;
75. }
76.  
77. /**始终记住, 通过模型来修改显示. 而不要试图直接修改显示*/
78. - (void)downloadImg:(NSIndexPath *)indexPath {
79. XNApp *app  = self.appList[indexPath.row]; //取得改行对应的模型
80.  
81. [self.queue addOperationWithBlock: ^{
82. NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]]; //得到图像数据
83. UIImage *image = [UIImage imageWithData:imgData];
84.  
85. //在主线程中更新UI
86. [[NSOperationQueue mainQueue] addOperationWithBlock: ^{
87. //通过修改模型, 来修改数据
88. app.image = image;
89. //刷新指定表格行
90. [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
91. }];
92. }];
93. }
94.  
95. @end

 

上述代码只是做了内存缓存,而每次重新进入应用时,还会从网上重新下载。如果要继续优化上面的代码,需要自己去实现本地缓存。


二、使用第三方框架SDWebImage。(非常优秀)

 

*特点 :依赖的库很少.功能全面。 *自动实现磁盘缓存: *缓存图片名字是以MD5进行加密的后的名字进行命名.(因为加密那堆字串是唯一的) *[imageViewsd_setImageWithURL:v.fullImageURL placeholderImage:[UIImage imageNamed:@”xxxxx”]]. *就一个方法就实现了多线程带缓冲等效果.(可用带参数的方法,具体可看头文件)
用SDWebImage修改上面的方法后的代码可简化为:

01. #pragma mark - 数据源方法
02. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
03. return self.appList.count;
04. }
05.  
06. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
07. static NSString *ID = @"Cell";
08. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
09.  
10. //用模型来填充每个cell
11. XNApp *app = self.appList[indexPath.row];
12. cell.textLabel.text = app.name;  //设置文字
13.  
14. //  //设置图像: 模型中图像为nil时用默认图像,并下载图像. 否则用模型中的内存缓存图像.
15. //  if (!cell.imageView.image) {
16. //      cell.imageView.image = [UIImage imageNamed:@"user_default"];
17. //
18. //      [self downloadImg:indexPath];
19. //  }
20. //  else {
21. //      //直接用模型中的内存缓存
22. //      cell.imageView.image = app.image;
23. //  }
24.  
25.  
26. //使用SDWebImage来完成上面的功能. 针对ImageView.
27. //一句话, 自动实现了异步下载. 图片本地缓存. 网络下载. 自动设置占位符.
28. [cell.imageView sd_setImageWithURL:[NSURL URLWithString:app.icon] placeholderImage:[UIImage imageNamed:@"user_default"]];
29.  
30.  
31. return cell;
32. }
33.  
34. /**始终记住, 通过模型来修改显示. 而不要试图直接修改显示*/
35. //- (void)downloadImg:(NSIndexPath *)indexPath {
36. //  XNApp *app  = self.appList[indexPath.row]; //取得改行对应的模型
37. //
38. //  [self.queue addOperationWithBlock: ^{
39. //      NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]]; //得到图像数据
40. //      UIImage *image = [UIImage imageWithData:imgData];
41. //
42. //      //在主线程中更新UI
43. //      [[NSOperationQueue mainQueue] addOperationWithBlock: ^{
44. //          //通过修改模型, 来修改数据
45. //          app.image = image;
46. //          //刷新指定表格行
47. //          [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
48. //      }];
49. //  }];
50. //}
51.  
52. @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 延迟显示占位图片

出处:http://blog.csdn.net/xn4545945

如何联系我:【万里虎】www.bravetiger.cn 【QQ】3396726884 (咨询问题100元起,帮助解决问题500元起) 【博客】http://www.cnblogs.com/kenshinobiy/
目录
相关文章
|
1月前
|
机器学习/深度学习 PyTorch 算法框架/工具
目标检测实战(一):CIFAR10结合神经网络加载、训练、测试完整步骤
这篇文章介绍了如何使用PyTorch框架,结合CIFAR-10数据集,通过定义神经网络、损失函数和优化器,进行模型的训练和测试。
89 2
目标检测实战(一):CIFAR10结合神经网络加载、训练、测试完整步骤
|
3月前
|
移动开发 TensorFlow 算法框架/工具
只保存和加载网络权重
【8月更文挑战第21天】只保存和加载网络权重。
34 2
|
18天前
|
存储 缓存 Dart
Flutter&鸿蒙next 封装 Dio 网络请求详解:登录身份验证与免登录缓存
本文详细介绍了如何在 Flutter 中使用 Dio 封装网络请求,实现用户登录身份验证及免登录缓存功能。首先在 `pubspec.yaml` 中添加 Dio 和 `shared_preferences` 依赖,然后创建 `NetworkService` 类封装 Dio 的功能,包括请求拦截、响应拦截、Token 存储和登录请求。最后,通过一个登录界面示例展示了如何在实际应用中使用 `NetworkService` 进行身份验证。希望本文能帮助你在 Flutter 中更好地处理网络请求和用户认证。
135 1
|
19天前
|
缓存 JavaScript
Vue加载网络组件(远程组件)
【10月更文挑战第23天】在 Vue 中实现加载网络组件(远程组件)可以通过多种方式来完成。
|
6月前
|
存储 缓存 安全
基于iOS平台的高效图片缓存策略实现
【4月更文挑战第22天】 在移动应用开发中,图片资源的加载与缓存是影响用户体验的重要因素之一。尤其对于iOS平台,由于设备存储空间的限制以及用户对流畅性的高要求,设计一种合理的图片缓存策略显得尤为关键。本文将探讨在iOS环境下,如何通过使用先进的图片缓存技术,包括内存缓存、磁盘缓存以及网络请求的优化,来提高应用的性能和响应速度。我们将重点分析多级缓存机制的设计与实现,并对可能出现的问题及其解决方案进行讨论。
|
3月前
|
安全 网络安全 Android开发
安卓与iOS开发:选择的艺术网络安全与信息安全:漏洞、加密与意识的交织
【8月更文挑战第20天】在数字时代,安卓和iOS两大平台如同两座巍峨的山峰,分别占据着移动互联网的半壁江山。它们各自拥有独特的魅力和优势,吸引着无数开发者投身其中。本文将探讨这两个平台的特点、优势以及它们在移动应用开发中的地位,帮助读者更好地理解这两个平台的差异,并为那些正在面临选择的开发者提供一些启示。
127 56
|
3月前
|
缓存 NoSQL Linux
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
128 1
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
|
3月前
|
存储 缓存 监控
警惕网络背后的陷阱:揭秘DNS缓存中毒如何悄然改变你的网络走向
【8月更文挑战第26天】DNS缓存中毒是一种网络攻击,通过篡改DNS服务器缓存,将用户重定向到恶意站点。攻击者利用伪造响应、事务ID猜测及中间人攻击等方式实施。这可能导致隐私泄露和恶意软件传播。防范措施包括使用DNSSEC、限制响应来源、定期清理缓存以及加强监控。了解这些有助于保护网络安全。
87 1
|
6月前
|
存储 缓存 编解码
实现iOS平台的高效图片缓存策略
【4月更文挑战第23天】在移动应用开发领域,尤其是图像处理密集型的iOS应用中,高效的图片缓存策略对于提升用户体验和节省系统资源至关重要。本文将探讨一种针对iOS平台设计的图片缓存方案,该方案通过结合内存缓存与磁盘缓存的多层次结构,旨在优化图片加载性能并降低内存占用。我们将深入分析其设计理念、核心组件以及在实际场景中的应用效果,同时对比其他常见缓存技术的优势与局限。
|
3月前
|
缓存
Flutter Image从网络加载图片刷新、强制重新渲染
Flutter Image从网络加载图片刷新、强制重新渲染
116 1

热门文章

最新文章