UIday1702:KVO 观察者设计模式 代码实现 常用

KVO 观察者设计模式 代码实现 常用


前提需要将之前编辑好的两个DownLoadTool文件拖过来

(DownLoadTool.h  DownLoadTool.m)


TableViewController.m

#import "TableViewController.h"
#import "TableViewCell.h"
#import "Model.h"
#import "DownLoadTool.h" 

@interface TableViewController ()

@property(nonatomic,strong)NSMutableArray * dataArray;

@end

@implementation TableViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //初始化数组
    self.dataArray = [NSMutableArray array];
    //请求数据
    [DownLoadTool downLoadWithURL:@"http://project.lanou3g.com/teacher/yihuiyun/lanouproject/activitylist.php" method:@"GET" param:nil passValue:^(id value) {
        
        //解析数据
        NSDictionary * tempDict = [NSJSONSerialization JSONObjectWithData:value options:(NSJSONReadingAllowFragments) error:nil];
        
        for (NSDictionary * dict in tempDict[@"events"]) {
            Model * m = [[Model alloc]init];
            
            [m setValuesForKeysWithDictionary:dict];
            [self.dataArray addObject:m];
        }
        //更新数据
        [self.tableView reloadData];
        
    }];
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
#warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
#warning Incomplete method implementation.
    // Return the number of rows in the section.
    return self.dataArray.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
    
    //获取对应的model对象
    Model * m = self.dataArray[indexPath.row];
    
    //赋值
    cell.lab.text = m.title;
    
    //加载图片
    if (m.loadImage == nil && m.isLoading == NO) {
        //如果满足这个条件,说明图片可以显示
        //这种情况就启用占位图
        cell.imV.image = [UIImage imageNamed:@"000.png"];
        
        //加载图片数据
        [m downLoadImage];
        
        //添加观察者
        //__bridge_retained 桥接的作用将c语言转成OC
        [m addObserver:self forKeyPath:@"loadImage" options:(NSKeyValueObservingOptionNew) context:(__bridge_retained void *)(indexPath)];
        
    }else{
        
        //加载中
        //判断图片是否下载完成
        if (m.image == nil) {
            //如果未完成,使用占位符
            cell.imV.image = [UIImage imageNamed:@"000.png"];
        }else{
            //完成 就是用下载后的图片
            cell.imV.image = m.loadImage;
        }
    }
    return cell;
}

//
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    
    // 1 拿到新值
    UIImage * newImage = change[NSKeyValueChangeNewKey];
    
    // 判空
    if ([newImage isEqual:[NSNull null]]) {
        return;
    }
    
    // 2 拿到当前显示的cell(index)
    NSArray * indexArray = [self.tableView indexPathsForVisibleRows];
    
    // 3 拿到刚请求到图片的cell的indexPath
    // __bridge NSIndexPath *
    NSIndexPath * indexPath = (__bridge NSIndexPath *)(context);
    
    // 4 判断是否正在显示
    if ([indexArray containsObject:indexPath]) {
        
        // 拿到cell
        TableViewCell * cell = (TableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
        
        // 换图片
        cell.imV.image = newImage;
    }
    
    // 移除观察者
    [object removeObserver:self forKeyPath:@"loadImage"];
       
}

@end

TableViewCell.h

#import <UIKit/UIKit.h>

@interface TableViewCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UILabel *lab;
@property (weak, nonatomic) IBOutlet UIImageView *imV;

@end

Model.h

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>


@interface Model : NSObject

@property(nonatomic,copy)NSString * image;
@property(nonatomic,copy)NSString * title;

// 用来缓存图片
@property(nonatomic,strong)UIImage * loadImage;

// 判断图片是否正在加载
@property(nonatomic,assign)BOOL isLoading;

// 加载图片
-(void)downLoadImage;

@end

Model.m

#import "Model.h"
#import "DownLoadTool.h"

@implementation Model

-(void)downLoadImage{
    
    [DownLoadTool downLoadWithURL:_image method:@"GET" param:nil passValue:^(id value) {
        
        self.loadImage = [UIImage imageWithData:value];
        
        //加载完成 (意味着不在加载中)
        _isLoading = NO;
        
    }];
    
    // 加载中
    _isLoading = YES;
    
}

-(void)setValue:(id)value forUndefinedKey:(NSString *)key{
    
}

@end



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值