iOS中的键值编码(KVC)与观察(KVO)(一)

/ 0评 / 0

键值编码(KVC)允许开发者通过名字访问对象属性,而无需调用明确的存取方法,这样,开发者就能在运行时确定属性的绑定,而不是编译时确定,从而得到更灵活和易于重用的对象,为了获得这种灵活性,对象需要用特定的方式来命名方法,这种命名方式就叫做键值编码。
有了键值编码,那么我们就可以使用键值观察了,键值观察(KVO)就是通知某些对象关于其他对象的属性值发生变化的一种机制,Cocoa中有若干观察者,包括委托和 NSNotification,但是KVO的开销更小。被观察者的对象不需要有有任何额外的代码来通知观察者,而如果没有观察者,KVO就没有运行时的消耗,只有对象被真正观察时,KVO系统才添加通知代码。

@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *sex;
@property (nonatomic, copy) NSString *age;
@property (nonatomic, copy) NSString *height;
@end

@implementation Person
@end

//控制器
@interface ViewController ()
@property (nonatomic, retain) Person *person;
@end

static NSString *const KVO_CONTEXT_AGE_CHANGED = @"KVO_CONTEXT_AGE_CHANGED";

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        self.person = [[Person alloc] init];
        //kvc设置值
   	[self.person setValue:@"大叔" forKey:@"name"];
	[self.person setValue:@"90" forKey:@"age"];

	//kvc取值的两种方法
	NSLog(@"%@",[self.person valueForKey:@"name"]);
	NSLog(@"%@",[self  valueForKeyPath:@"person.name"]); //这种必须是对应某个类的属性的属性才行

	//kvo添加观察者
	[self.person addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:(__bridge void * _Nullable)(KVO_CONTEXT_ADDRESS_CHANGED)];
	UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(20, 60, 100, 40)];
	button.backgroundColor = [UIColor greenColor];
	[button addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
	[self.view addSubview:button];
 
- (void)btnClick{
        [self.person setValue:@"100" forKey:@"age"];
}

//观察者调用的方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
        if(context == (__bridge void * _Nullable)(KVO_CONTEXT_ADDRESS_CHANGED)) {
            NSString *name = [object valueForKey:@"name"];
            NSString *address = [object valueForKey:@"age"];
            NSLog(@"%@ has a 升级了: %@", name, address);
        }
}
@end

打印的结果如下
2016-05-30 11:32:52.788 DCRequestTest[2116:31182] 大叔
2016-05-30 11:32:52.848 DCRequestTest[2116:31182] 大叔
2016-05-30 11:32:52.913 DCRequestTest[2116:31182] 大叔 has a 升级了: 100
2016-05-30 11:32:53.052 DCRequestTest[2116:31182] 大叔 has a 升级了: 100
2016-05-30 11:32:53.212 DCRequestTest[2116:31182] 大叔 has a 升级了: 100
2016-05-30 11:32:53.348 DCRequestTest[2116:31182] 大叔 has a 升级了: 100

评论已关闭。