KVC | Key Value Coding | 键值编码
KVO | Key Value Observer | 键值监听
---------------------------
KVC实现属性的动态设置和读取
KVC的操作方法由NSKeyValueCoding协议提供,而NSObject就实现了这个协议,也就是说ObjC中几乎所有的对象都支持KVC操作,常用的KVC操作方法
动态设置: setValue:属性值 forKey:属性名(用于简单路径)、setValue:属性值 forKeyPath:属性路径(用于复合路径,例如Person有一个Account类型的属性(Account里面有个name属性),那么在Person里面account.name就是一个复合属性)
动态读取: valueForKey:属性名 、valueForKeyPath:属性名(用于复合路径)
----------------------------
KVO实行属性的实时监听KVO其实是一种观察者模式,利用它可以很容易实现视图组件和数据模型的分离,当数据模型的属性值改变之后作为监听器的视图组件就会被激发,激发时就会回调监听器自身。在ObjC中要实现KVO则必须实现NSKeyValueObServing协议,不过幸运的是NSObject已经实现了该协议,因此几乎所有的ObjC对象都可以使用KVO。
在ObjC中使用KVO操作常用的方法如下:
注册指定Key路径的监听器: addObserver: forKeyPath: options: context:
删除指定Key路径的监听器: removeObserver: forKeyPath、removeObserver: forKeyPath: context:
回调监听: observeValueForKeyPath: ofObject: change: context:
KVO的使用步骤也比较简单:
- 通过addObserver: forKeyPath: options: context:为被监听对象(它通常是数据模型)注册监听器
- 重写监听器的observeValueForKeyPath: ofObject: change: context:方法
eg:
//
// ViewController.m
// KVC
//
// Created by Wu on 16/4/5.
// Copyright © 2016年 Wu. All rights reserved.
//
#import "ViewController.h"
#import <UIKit/UIKit.h>
@interface ViewController ()
{
}
@property(nonatomic , strong)UITextField *field;
@property(nonatomic , strong)UIButton *saveBtn;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *name = @"我是个大帅比";
self.name = name;
UILabel *textLabel = [[UILabel alloc]initWithFrame:CGRectMake(50, 50, self.view.bounds.size.width - 100, 50)];
textLabel.layer.cornerRadius = 15;
textLabel.backgroundColor = [UIColor grayColor];
textLabel.text = self.name;
self.textLabel = textLabel;
[self.view addSubview:self.textLabel];
[self addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
UITextField *filed = [[UITextField alloc]initWithFrame:CGRectMake(20, 200, self.view.bounds.size.width - 40,100)];
filed.backgroundColor = [UIColor grayColor];
[filed addTarget:self action:@selector(valueChange:) forControlEvents:UIControlEventEditingChanged];
self.field = filed;
[self.view addSubview:self.field];
// UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
// btn.frame = CGRectMake(100, 400, self.view.bounds.size.width - 200,30);
// btn.layer.cornerRadius = 5;
// btn.backgroundColor = [UIColor yellowColor];
// [btn addTarget:self action:@selector(saveData:) forControlEvents:UIControlEventTouchUpInside];
// self.saveBtn = btn;
// [self.view addSubview:self.saveBtn];
}
- (void)valueChange:(UITextField *)sender {
self.name = sender.text;
}
- (void)saveData:(UIButton *)sender {
self.name = self.field.text;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
self.textLabel.text = self.name;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end