iOS网络加载图片缓存与SDWebImage

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值