KVO应用示例(附代码)

键值观察就是对象属性表换透明的通知观察者的一种机制。它是通知某些对象关于其他对象的属性值发生变化的一种机制。不需要对被观察者的Class进行修改,永远是观察你的类做事情。
这里主要实现一个无论对象什么时候发生变化,都可以让表格单元自动更新。观察者为self.object,被观察的对象属性为self.property。

#import <UIKit/UIKit.h>
@interface TableViewCell : UITableViewCell
-(id)initWithReuseIdentifer:(NSString *) identifier;
@property (nonatomic, readwrite,strong) id object;
@property (nonatomic,readwrite,copy) NSString *property;
@end
#import "TableViewCell.h"

@implementation TableViewCell

-(BOOL)isReady
{
    return (self.object && [self.property length] > 0);
}


-(void)update
{
    NSString *text;
    if (self.isReady) {
        id value = [self.object  valueForKeyPath:self.property];
        text = [value description];
    } else {
        text = @"";
    }
    
    self.textLabel.text = text;
}


-(id)initWithReuseIdentifer:(NSString *) identifier
{
    return [self initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}


-(void)removeObservation
{
    if (self.isReady) {
        [self.object removeObserver:self forKeyPath:self.property];
    }
}

-(void)addObservation {
    if (self.isReady) {
        //self.object为表格控制器,将self作为context指针传递,以便在回调函数observeValueForKeyPath中可以判断这是我们观察的事件
        [self.object addObserver:self forKeyPath:self.property options:0 context:(void *)self];
    }
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    
    if ((__bridge id)context == self) {
        [self update];
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

-(void)dealloc
{
    if (_object && [_property length] > 0) {
        [_object removeObserver:self forKeyPath:_property context:(__bridge void * _Nullable)(self)];
    }
}

-(void)setObject:(id)object
{
    [self removeObservation];
    _object = object;
    [self addObservation];
    [self update];
}

-(void)setProperty:(NSString *)property
{
    [self removeObservation];
    _property = property;
    [self addObservation];
    [self update];
}

@end
控制器代码
#import "TableViewController.h"
#import "TableViewCell.h"

@interface TableViewController ()


@property(nonatomic,retain) NSTimer *timer;
@property (readwrite,retain ) NSDate *now;
@end

@implementation TableViewController


-(void)updataNow {
    self.now = [NSDate date];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.timer = [NSTimer timerWithTimeInterval:0.5 target:self selector:@selector(updataNow) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}

#pragma mark - Table view data source

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
 
    return 100;
}
- (TableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    //注意自定义TableViewCell的时,Xib文件不要在设置CellIdentifier
    static NSString *CellIdentifier = @"wubiao";
    TableViewCell *wubiaoCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
    if (wubiaoCell == nil) {
        wubiaoCell = [[TableViewCell alloc] initWithReuseIdentifer:CellIdentifier];
        wubiaoCell.backgroundColor = [UIColor greenColor];
        [wubiaoCell setProperty:@"now"];
        [wubiaoCell setObject:self];
    }
    return wubiaoCell;
}

-(void)dealloc
{
    self.timer = nil;
    self.now =nil;
}

@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,211评论 30 472
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,958评论 19 139
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,776评论 0 9
  • 2017-09-05 股市早餐 一、新股申购 英派斯(002899) 英派斯此次发行总数3000万股,网上发行为1...
    db1eae6e5a78阅读 780评论 0 0
  • 刚刚开始自学,网上很多相关帖子上来直接报上两页菜名,初一看很有武侠小说里说书人的感觉.这本书怎样怎样,那本书如何如...
    youcansea阅读 1,900评论 0 1