鍵值觀察就是對象屬性表換透明的通知觀察者的一種機(jī)制知态。它是通知某些對象關(guān)于其他對象的屬性值發(fā)生變化的一種機(jī)制。不需要對被觀察者的Class進(jìn)行修改,永遠(yuǎn)是觀察你的類做事情。
這里主要實現(xiàn)一個無論對象什么時候發(fā)生變化,都可以讓表格單元自動更新。觀察者為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指針傳遞,以便在回調(diào)函數(shù)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文件不要在設(shè)置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