iOS网络加载图片缓存与SDWebImage

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

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

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

时间: 2024-10-12 13:17:35

iOS网络加载图片缓存与SDWebImage的相关文章

【iOS】网络加载图片缓存与SDWebImage

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

iOS网络加载图片缓存策略之ASIDownloadCache缓存优化

在我们实际工程中,很多情况需要从网络上加载图片,然后将图片在imageview中显示出来,但每次都要从网络上请求,会严重影响用户体验,为了不是每次显示都需要从网上下载数据,希望将图片放到本地缓存,因此我们需要一个好的的缓存策略,今天我将我在项目工程中的实际经验分享给大家,我这里主要介绍一下强大的ASIHTTPRequest的缓存策略,以及使用方法. AD: 在我们实际工程中,很多情况需要从网络上加载图片,然后将图片在imageview中显示出来,但每次都要从网络上请求,会严重影响用户体验,为了不

LruCache:从网络加载图片缓存实例

OOM异常 堆内存用于存储实例对象,当程序不断创建对象,并且对象都有引用指向,那么垃圾回收机制就不会清理这些对象,当对象多到挤满堆内存的上限后,就产生OOM异常.Android系统为每个应用程序使用的内存设置了一个上限.这个上限值可以用下面的方法取得: long maxSize = Runtime.getRuntime().maxMemory(); OOM异常通常分为下面几种情况:1.内存泄漏导致的OOM:new出来的很多对象已经不需要了,但仍然有引用指向,所以垃圾回收机制无法回收. 其场景类似

Android异步加载学习笔记之四:利用缓存优化网络加载图片及ListView加载优化

如果不做任何处理,直接用网络加载图片在网速快的情况下可能没什么不好的感觉,但是如果使用移动流量或是网络不好的时候,问题就来了,要么用户会抱怨流量使用太多,要么抱怨图片加载太慢,如论从哪个角度出发,都不是好的体验!要提高用户体验,我们就要使用缓存.Android中数据缓存的方式有很多,相关介绍的文章也比较多,比如http://blog.csdn.net/dahuaishu2010_/article/details/17093139和http://www.jb51.net/article/38162

三种基本网络加载图片方式

代码片段(6) [全屏查看所有代码] 1. [代码]普通加载网络方式     ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 public class NormalLoadPictrue {   

网络多线程 ---实现网络加载图片

案例要求:网络加载图片,随机加载到设置好的视图上 实现的效果图如下: 具体代码如下: // //  ViewController.m //  0603---NSOperationQueue #import "ViewController.h" @interface ViewController () @property (nonatomic,strong) NSMutableArray * imageArray; @end @implementation ViewController

android 网络加载图片,对图片资源进行优化,并且实现内存双缓存 + 磁盘缓存

经常会用到 网络文件 比如查看大图片数据 资源优化的问题,当然用开源的项目  Android-Universal-Image-Loader  或者 ignition 都是个很好的选择. 在这里把原来 写过的优化的代码直接拿出来,经过测试千张图片效果还是不错的. 免费培训课:http://www.jinhusns.com/Products/Curriculum/?type=xcj 工程目录 至于 Activity 就是加载了 1个网格布局 01./** 02.*   实现 异步加载 和   2级缓

登录圆形头像之网络加载与缓存到本地

Android开发中常常有用户头像显示,似乎大多数都是圆形显示,如果每次加载网络头像,会频繁的请求网络,所以本文主要说的是登录时的头像网络加载和缓存到本地,以便于下次加载时直接从本地获取即可. 效果图 自定义控件实现圆形头像显示请看, Android自定义ImageView实现图片圆形 ,椭圆和矩形圆角显示 这篇博客即可. 代码: public class MainActivity extends Activity implements OnClickListener { private Ima

android 网络加载图片

通过网络链接加载网络图片 加权限,允许访问网络 <uses-permission android:name="android.permission.INTERNET"/> MainActivity package com.chuanxidemo.shaoxin.demo08; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; imp