1.简介
在ios里,可以添加观察者模式,来实现某个property更改后,通知指定的类。
然后到observeValueForKeyPath:ofObject:change:context:提供处理
1 [object addObserver: observer forKeyPath: @"frame" options: 0 context: nil];
调用方法是里:
object : 被观察对象
observer: 观察对象
forKeyPath里面带上property的name,如UIView的frame、center等等
options: 有4个值,分别是:
NSKeyValueObservingOptionNew 把更改之前的值提供给处理方法
NSKeyValueObservingOptionOld 把更改之后的值提供给处理方法
NSKeyValueObservingOptionInitial 把初始化的值提供给处理方法,一旦注册,立马就会调用一次。通常它会带有新值,而不会带有旧值。
NSKeyValueObservingOptionPrior 分2次调用。在值改变之前和值改变之后。
注:例子里的0就代表不带任何参数进去
context: 可以带入一些参数,其实这个挺好用的,任何类型都可以,自己强转就好了。
处理方法里:
keyPath: 对应forKeyPath
object: 被观察的对象
change: 对应options里的NSKeyValueObservingOptionNew、NSKeyValueObservingOptionOld等
context: 对应context
//
// KVCTableViewController.m
// KVC
//
// Created by tinghou on 16/5/30.
//
#import <UIKit/UIKit.h>
@interface KVCTableViewCell : UITableViewCell
- (id)initWithReuseIdentifier:(NSString*)identifier;
@property (nonatomic, readwrite, strong) id object;
@property (nonatomic, readwrite, copy) NSString *property;
@end
//
// KVCTableViewController.m
// KVC
//
// Created by tinghou on 16/5/30.
//
#import "KVCTableViewCell.h"
@implementation KVCTableViewCell
- (BOOL)isReady {
return (self.object && [self.property length] > 0);
}
- (void)update {
self.textLabel.text = self.isReady ?
[[self.object valueForKeyPath:self.property] description]
: @"";
}
- (id)initWithReuseIdentifier:(NSString *)identifier {
return [super initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:identifier];
}
- (void)removeObservation {
if (self.isReady) {
[self.object removeObserver:self
forKeyPath:self.property];
}
}
#pragma mark 添加观察者
- (void)addObservation {
if (self.isReady) {
[self.object addObserver:self forKeyPath:self.property
options:0
context:(void*)self];
}
}
#pragma mark 一旦监听到改变就会调用
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)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:(void *)self];
}
}
- (void)setObject:(id)anObject {
[self removeObservation];
_object = anObject;
[self addObservation];
[self update];
}
- (void)setProperty:(NSString *)aProperty {
[self removeObservation];
_property = aProperty;
[self addObservation];
[self update];
}
@end
//
// KVCTableViewController.m
// KVC
//
// Created by tinghou on 16/5/30.
//
#import "KVCTableViewController.h"
#import "KVCTableViewCell.h"
#import "RNTimer.h"
@interface KVCTableViewController ()
@property (readwrite, strong) RNTimer *timer;
@property (readwrite, strong) NSDate *now;
@end
@implementation KVCTableViewController
- (void)updateNow {
self.now = [NSDate date];
}
- (void)viewDidLoad {
[self updateNow];
__weak id weakSelf = self;
self.timer =
[RNTimer repeatingTimerWithTimeInterval:1
block:^{
[weakSelf updateNow];
}];
}
- (void)viewDidUnload {
self.timer = nil;
self.now = nil;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return 100;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"KVCTableViewCell";
KVCTableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[KVCTableViewCell alloc]
initWithReuseIdentifier:CellIdentifier];
[cell setProperty:@"now"];
[cell setObject:self];
}
return cell;
}
@end
项目目录: