TableView 异步下载图片

ImageDownloader.h

#pragma mark - 声明block

//1,声明block

typedef void(^Result) (UIImage *img);

@interface ImageDownloaderViewController : UIViewController

#pragma mark - 声明方法

//block 做参数

//ImageDownloader 允许外界指定URL,提供 开始下载 和 取消下载 功能,并提供delegate或block将图⽚片传递给外界。

+ (void)imageDownloaderWithUrlStr:(NSString *)urlStr result:(Result)result;

ImageDownloader.m

+ (void)imageDownloaderWithUrlStr:(NSString *)urlStr result:( Result)result

{

NSURL *url = [NSURL URLWithString:urlStr];

NSURLRequest *request = [NSURLRequest requestWithURL:url];

[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue new]autorelease] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

//把请求的二进制数据 转成图片

UIImage *image = [UIImage imageWithData:data];

//回到主线程调用

dispatch_sync(dispatch_get_main_queue(), ^{

//调用block

result(image);

});

}];

}

TableViewController.m

//加载数据

- (void)loadDataAndShow

{

NSURL *url = [NSURL URLWithString:URL_NEW];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

[request setHTTPMethod:@"GET"];

__block NewsTableViewController *weakSelf = self;

NSOperationQueue *queue = [[NSOperationQueue new] autorelease];

//建立连接,

[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];

//取大字典数据

//从key为result的数组中 取字典

//在此循环完成 即图片赋值完成

for (NSDictionary *dic in dict[@"result"]) {

//创建模型

News *new = [News new];

NSLog(@"模型创建,图片 开始下载");

//此时 图片开始下载

[new setValuesForKeysWithDictionary:dic];

[weakSelf.allDataMutableArray addObject:new];

[new release];

}

//回主线程

dispatch_sync(dispatch_get_main_queue(), ^{

//先刷新UI再拿到图片

[weakSelf.tableView reloadData];

NSLog(@" 刷新UI");

});

}];

}

- (void)didReceiveMemoryWarning {

[super didReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

#warning Incomplete method implementation.

// Return the number of rows in the section.

return _allDataMutableArray.count;

}

//显示Cell

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

NSLog(@"  显示 一个 cell");

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"new" forIndexPath:indexPath];

// Configure the cell...

News *new = _allDataMutableArray[indexPath.row];

cell.textLabel.text = new.movieName;

cell.detailTextLabel.text = new.movieId;

//如果图片数据请求下来,就赋值显示。如果没有,就监听

if (new.imageData != nil) {

cell.imageView.image = new.imageData;

}else{

NSLog(@" 图片没请求下来---》》》监听 ");

//KVO (1,注册监听)设置监听图片数据

//new 被监听

//self  监听者

//keypath  监听属性

//options   监听旧值 还是 新值

//控制器 观察 -》模型(在控制器中观察)

[new addObserver:self forKeyPath:@"imageData" options:NSKeyValueObservingOptionNew context:indexPath];

}

return cell;

}

#pragma mark - (2,实现回调方法)  KVO 监听被执行的方法,对象属性变化,即调用

//tableView 通过KVO观察 下载数据 及时更新页面

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

//判断标志

if ([keyPath isEqualToString:@"imageData"]) {

//1, 获取新图片数据

UIImage *newImageData = change[NSKeyValueChangeNewKey];

//2, 获取cell

NSIndexPath *indexPath = (NSIndexPath *)context;

UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

cell.imageView.image = newImageData;

//3, 刷新当前行

[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

//4,取消监听

[object removeObserver:self forKeyPath:keyPath];

NSLog(@"(监听值变化)拿到图片了。。。。。。");

}

}

//模型.h

@interface News : NSObject

@property(nonatomic,copy)NSString *movieId;

@property(nonatomic,copy)NSString *movieName;

@property(nonatomic,copy)NSString *pic_url;

//Model类注意事项:

//1、除了包含必要的数据外,还要包含⼀一个ImageDownloader对象。

//2、包含⼀一个image。

//3、包含⼀一个图⽚片是否正在下载的BOOL值。(⽤用于判断是否需要开始 下载)

@property(nonatomic,retain) UIImage *imageData;

//模型.m

#pragma mark - 重写pic_url 的 setter

//为了能正确显示图片,Model类应该提供图片获取功能(Model通过 ImageDownloader下载图片,供cell使用)

- (void)setPic_url:(NSString *)pic_url

{

if (_pic_url != pic_url) {

[_pic_url release];

_pic_url = [pic_url retain];

//

//使用block 异步加载图片

__block News *weakNews = self;

[ImageDownloaderViewController imageDownloaderWithUrlStr:self.pic_url result:^(UIImage *img) {

//将block 显示到imageView上

//在这使用,就在这实现(模型中实现block)

weakNews.imageData = img;

NSLog(@"--------------拿到图片,赋值显示 NEws");

}];

}

}

TableView_图片异步加载 KVO的更多相关文章

  1. 图片异步加载 ,KVO

    图片异步下载类目: .h #import <UIKit/UIKit.h> typedef void (^ImageBlock)(UIImage *img); @interface UIIm ...

  2. Android-Universal-Image-Loader 图片异步加载类库的使用

    在博客中看到一篇利用组件进行图片异步加载的文章在此作记录 原文:http://blog.csdn.net/vipzjyno1/article/details/23206387 这个图片异步加载并缓存的 ...

  3. Android图片异步加载框架Android-Universal-Image-Loader

    版权声明:本文为博主原创文章,未经博主允许不得转载. Android-Universal-Image-Loader是一个图片异步加载,缓存和显示的框架.这个框架已经被很多开发者所使用,是最常用的几个 ...

  4. Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)

    这个图片异步加载并缓存的类已经被很多开发者所使用,是最常用的几个开源库之一,主流的应用,随便反编译几个火的项目,都可以见到它的身影. 可是有的人并不知道如何去使用这库如何进行配置,网上查到的信息对于刚 ...

  5. Android ListView 图片异步加载和图片内存缓存

    开发Android应用经常需要处理图片的加载问题.因为图片一般都是存放在服务器端,需要联网去加载,而这又是一个比较耗时的过程,所以Android中都是通过开启一个异步线程去加载.为了增加用户体验,给用 ...

  6. Android 图片异步加载的体会,SoftReference已经不再适用

      在网络上搜索Android图片异步加载的相关文章,目前大部分提到的解决方案,都是采用Map<String, SoftReference<Drawable>>  这样软引用的 ...

  7. 【转】Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)

    Android-Universal-Image-Loader 原文地址:http://blog.csdn.net/vipzjyno1/article/details/23206387 这个图片异步加载 ...

  8. Android图片异步加载之Android-Universal-Image-Loader

    将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就 ...

  9. Android图片异步加载之Android-Universal-Image-Loader(转)

    今天要介绍的是Github上一个使用非常广泛的图片异步加载库Android-Universal-Image-Loader,该项目的功能十分强大,可以说是我见过的目前功能最全.性能最优的图片异步加载解决 ...

随机推荐

  1. 9. memcpy() memccpy() memmove() strcpy() memset()

    部分参考: http://www.cppblog.com/kang/archive/2009/04/05/78984.html 表头文件: #include <string.h>定义函数: ...

  2. AOJ 0121 广度优先搜索

    题意:7数码问题.在2×4的棋盘上,摆有7个棋子,每个棋子上标有1至7的某一数字,不同棋子上标的数字不相同.棋盘上还有一个空格(用0表示),与空格相邻(上下左右)的棋子可以移到空格中,该棋子原先位置成 ...

  3. I - Navigation Nightmare-poj 1984

    约翰和他的邻居生活在一个村庄里,他们的道路修建的很特别,都是正东正西或者正南正北,但是呢他们用一种方式描述他们和邻居的位置,比如说 6号 在1号 东面13处,那么我们就可以计算出来这两家的曼哈顿距离, ...

  4. 利用Jenkins自动部署工具间接构建kettle的调度平台

    关于Jenkins的介绍我就不说了,自己百度,因为这个工具调用脚本只是他的功能的冰山一角,其他功能我也不能理解,因为不是那个领域.        下面我就介绍一下为什么我们需要一个调度平台,以及学习完 ...

  5. POJ3080:Blue Jeans

    Description The Genographic Project is a research partnership between IBM and The National Geographi ...

  6. motan源码分析八:涉及到底层的客户端调用

    之前我们分析了客户端调用服务端的源码,但是没有涉及到通讯层和序列化层,本文将之前讲过的内容做一次串联. 1.上层通过动态代理调用refer的call,每个refer又对应一个nettyclient,下 ...

  7. Android BaseAdapter ListView (明星简介列表)

    1.搭建布局 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" andro ...

  8. Robotium--通过Id寻找控件

    在自动化测试中,UI上经常有一些控件是没有名称的,那么此时,就可以通过id来找到这些控件. 案例:对两个EditText进行测试 package com.tangbc.tedit.test; impo ...

  9. 大数据笔记04:大数据之Hadoop的HDFS(基本概念)

    1.HDFS是什么? Hadoop分布式文件系统(HDFS),被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统.它和现有的分布式文件系统有很多共同点. 2.HDFS ...

  10. NYOJ-1070诡异的电梯【Ⅰ】

    这道题是个dp,主要考虑两种情况,刚开始我把状态转移方程写成了dp[i] = min(dp[i-1] + a, dp[i + 1] +b); 后来想想当推到dp[i]的时候,那个dp[i + 1]还没 ...