您的位置:首页 > 理论基础 > 计算机网络

iOS网络加载图片缓存与SDWebImage

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

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

tips:

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

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

view sourceprint?

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修改上面的方法后的代码可简化为:

view sourceprint?

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: