KVO监测Model图片加载
使用上一篇的ImageDownLoader类
目的:网络请求数据时,由于图片比较大,加载较慢,可以先加载数据,并显示,而图片可以之后分开加载,加载完再显示
详细步骤
- 在加载数据的model类中添加属性,方法及遵守协议
<ImageDownLoadDelegate>
// 请求图片类
@property (nonatomic, retain) ImageDownLoader *imageDownLoader;
// 显示的图片
@property (nonatomic, retain) UIImage *coverImage;
// 判断是否正在加载当中
@property (nonatomic, assign) BOOL isDownLoading;
// 声明一个请求图片的方法
- (void)downLoadImage;
- 实现图片加载方法,以及自定义ImageDownLoader类的代理方法
- (void)downLoadImage{
self.imageDownLoader = [[ImageDownLoader alloc] initWithUrl:self.image delegate:self];
[self.imageDownLoader imageDownLoadStart];
// 更改图片的加载状态
self.isDownLoading = YES;
}
// 实现代理方法
- (void)imageDownLoadSucceedWithData:(NSData *)data{
// 执行了这个方法 说明了加载数据完成了
// 赋值成功 值从无到有
self.coverImage = [UIImage imageWithData:data];
// 更改状态 加载完成 改成NO
self.isDownLoading = NO;
}
- (void)imageDownLoadFailedWithError:(NSError *)error{
self.isDownLoading = NO;
NSLog(@"%@",error);
}
- 在tableView中显示(在加载完文字数据之后)
// 加载占位图
cell.activityImageView.image = [UIImage imageNamed:@""];
// 两种NO的情况
// 不是正在加载时
// 1.图片还没有请求
// 2.图片已经加载完成
// (解决复用问题)
if (model.coverImage == nil && model.isDownLoading == NO) {
// 异步加载图片的方法
// 请求图片 Z
[model downLoadImage];
// 添加观察者
// 为了把图片显示到对应的图片上
// 需要把indexPath索引传递过去
[model addObserver:self forKeyPath:@"coverImage" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:indexPath];
}else{
// 只要走到这里就说明coverimage里有值了 直接进行重新赋值
cell.activityImageView.image = model.coverImage;
}
return cell;
}
// 键值观察的方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
// 一旦图片加载出来了 就会触发这个方法
// 把这张加载出来的图片显示到对应的cell上
// 有了indexPath 就可以把对应的cell取出来
// 取出cell 就可以 让cell显示图片
// 取出cell (转化context的类型)
ActivityListCell *cell = (ActivityListCell *)[self.tableView cellForRowAtIndexPath:(NSIndexPath *)context];
// 取图片
UIImage *image = change[@"new"];
// 显示图片
cell.activityImageView.image = image;
[object removeObserver:self forKeyPath:keyPath];
}