TableView_图片异步加载 KVO
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的更多相关文章
- 图片异步加载 ,KVO
图片异步下载类目: .h #import <UIKit/UIKit.h> typedef void (^ImageBlock)(UIImage *img); @interface UIIm ...
- Android-Universal-Image-Loader 图片异步加载类库的使用
在博客中看到一篇利用组件进行图片异步加载的文章在此作记录 原文:http://blog.csdn.net/vipzjyno1/article/details/23206387 这个图片异步加载并缓存的 ...
- Android图片异步加载框架Android-Universal-Image-Loader
版权声明:本文为博主原创文章,未经博主允许不得转载. Android-Universal-Image-Loader是一个图片异步加载,缓存和显示的框架.这个框架已经被很多开发者所使用,是最常用的几个 ...
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
这个图片异步加载并缓存的类已经被很多开发者所使用,是最常用的几个开源库之一,主流的应用,随便反编译几个火的项目,都可以见到它的身影. 可是有的人并不知道如何去使用这库如何进行配置,网上查到的信息对于刚 ...
- Android ListView 图片异步加载和图片内存缓存
开发Android应用经常需要处理图片的加载问题.因为图片一般都是存放在服务器端,需要联网去加载,而这又是一个比较耗时的过程,所以Android中都是通过开启一个异步线程去加载.为了增加用户体验,给用 ...
- Android 图片异步加载的体会,SoftReference已经不再适用
在网络上搜索Android图片异步加载的相关文章,目前大部分提到的解决方案,都是采用Map<String, SoftReference<Drawable>> 这样软引用的 ...
- 【转】Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
Android-Universal-Image-Loader 原文地址:http://blog.csdn.net/vipzjyno1/article/details/23206387 这个图片异步加载 ...
- Android图片异步加载之Android-Universal-Image-Loader
将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就 ...
- Android图片异步加载之Android-Universal-Image-Loader(转)
今天要介绍的是Github上一个使用非常广泛的图片异步加载库Android-Universal-Image-Loader,该项目的功能十分强大,可以说是我见过的目前功能最全.性能最优的图片异步加载解决 ...
随机推荐
- yui--datatable 更新table数据
使用render可以重新渲染datatable,之前添加的样式等信息也想相应会初始化,另外行定位等也会失效 使用updateRows方法不会删除样式等信息 更新datasource中_oData数据 ...
- Win8 系统下串口出现叹号 异常(10)
在网上找了些资料,自己试了一下可行,具体步骤就是把win8系统自动更新驱动的功能给关掉,然后自己下载可用的驱动.具体可以看 http://download.csdn.net/detail/wuu_ex ...
- SublimeText的使用
1.安装Sublime_text2.02文件:Sublime Text 2.0.2.tar.bz2 (1)官网下载地址:http://www.sublimetext.com/2 (2)将文件放到lin ...
- html+javascript实现可拖动弹出层、对话框、可提交
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org ...
- 一个C++的多态和虚函数实例
类的说明: code: #include<iostream> #include<string> #define PAI 3.1415926 using namespace st ...
- 解决Item控件抢占焦点
http://www.imooc.com/learn/372 在抢占焦点的控件加上 方法一: android:focusable="false" 方法二: 在外界布局上 andro ...
- Brunch:快捷的HTML5构建工具
Brunch,一个超快的HTML5构建工具.它可以(官方介绍): 编译你的脚本,模板,样式,链接它们, 将脚本和模板封装进common.js/AMD模块里,链接脚本和样式, 为链接文件生成源地图,复制 ...
- Asp.Net MVC 页面代码压缩筛选器-自定义删除无效内容
Asp.Net MVC 页面代码压缩筛选器 首先定义以下筛选器,用于代码压缩. /*页面压缩 筛选器*/ public class WhiteSpaceFilter : Stream { privat ...
- Linux 系统运行级别
Linux运行级别从0-6,共7个. 0:关机.不能将系统缺省运行级别设置为0,否则无法启动. 1:单用户模式,只允许root用户对系统进行维护. 2:多用户模式,但不能使用NFS(相当于Win ...
- codevs 2995 楼房
/*暴力30分*/ #include<iostream> #include<cstring> #include<cstdio> #include<map> ...