代码改变世界

ios - kvo观察者示例

2016-05-04 21:29  菜鸟Alex  阅读(243)  评论(0编辑  收藏  举报
  • 首先创建Person分类

#import <Foundation/Foundation.h>

@interface Person : NSObject



@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) float height;



@end

  • .m中不做任何事情

  • 控制器.m中


#import "ViewController.h"
#import "Person.h"
@interface ViewController ()

@property (nonatomic, strong) Person *per;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    Person * per = [Person new];
    per.name = @"zhangsan";
    per.height = 1.2;
    self.per = per;
    
    // kvo 为per.name添加观察者
    [per addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
    
    // kvo 为per.height添加观察者
    [per addObserver:self forKeyPath:@"height" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
    
}

  • 只要监听的属性name 和 height的值发生了改变就会触发下面的方法

/** 添加观察者必须要实现的方法 */
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
    /** 打印新老值 */
    // 从打印结果看 分别打印出了 name 与 height的新老值
    NSLog(@"old : %@  new : %@",[change objectForKey:@"old"],[change objectForKey:@"new"]);
//    NSLog(@"keypath :  %@",keyPath);
//    NSLog(@"change : %@",change);
    
}

  • 由于对person.name 以及height的属性都做了监听,只要触摸后属性的值发生改变就做得到通知触发通知方法 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context 则可以在其内部做你想要做的事

/** 触摸改变per.name属性值 */
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    self.per.name = @"helloworld";
    self.per.height = 3.3;
}


  • 一定要记得移除


/** 移除 */
-(void)dealloc{

    [self.per removeObserver:self forKeyPath:@"name" context:nil];
    [self.per removeObserver:self forKeyPath:@"height" context:nil];

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

@end

  • 注意点:
    1. 为某个对象的某个属性添加观察者,最后一定要移除,否则可能会崩溃
    1. 实现方法-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context则只要监听的属性发生改变就会触发.