UI:KVO、KVC

什么是KVC 什么是 KVO ?

KVC:(NSKey ValueCoding)”键-值  编码“是一种间接的访问对象属性(字符串表征)的机制。对象的属性都可以通过使用KVC机制用相同的方式访问。我们可以取而代之“设置器方法、点语法方法”去访问对象的属性。

KVO:(NSKey ValueObserving)"键-值 监听"是一种这样的机制,当对象的属性发生变化的时候,我们的监听者能够得到一个通知。

NSObject 类为所有的对象提供了一个自动检测能力的NSKey ValueObserving 协议。我们可以根据需要来打开这个监听机制。KVO是基于KVC而实现的。

KVC & KVO的使用

在使用KVC的时候,我们要注意,key 必须以小写字母开头,通常常和系统访问器方法同名。

获取属性:valueForKey:

设置属性:setValue: forKey:

KVC 对未定义的属性定义了 valueForUndefinedKey: 方法(重载方法获取定制的实现)

注意:KVC中的 value 都必须是对象。

基于KVC能够对对象的属性进行访问,当这个属性发生变化的时候,我们也能监听,这个监听的方法系统已经为我们实现了。我们所做的只需要去注册这个监听。注册之后就能很好的监听,属性的值变化了。下面就是KVO机制的注册和监听方法

1注册

-(void)addObserVer:(NSObject*)anObserver    forKeyPath:(NSString *)keyPath   options:(NSKeyValueObservingOptions)options   context:(void *)context

方法参数说明:keyPath 就是要观察的属性值,options 就是观察键值变化的选择 ,context 就是我们要传输的数据。其中options 是监听返回的字典所包含什么值。有两个常用的选项:NSKeyValueObservingOptionNew  返回的字典包含新值  NSKeyValueObservingOptionOld 指返回的字典包含旧值。

2.监听

-(void)obserValueForKeyPath:(NSString *)KeyPath   ofObject(id)object  change:(NSDictionary *)change  context:(void *)context  

其中 change 里存储了一些变化的数据,比如变化前的数据,变化后的数据。

实例代码:

———————————————————————————————————————————————(.m文件)


#import "AppDelegate.h"
#import "ViewController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    ViewController * vc = [[ViewController alloc]init];
    self.window.rootViewController = vc;
    return YES;
}
View Code Appdelegate文件
———————————————————————————————————————————————(.h文件)

#import <Foundation/Foundation.h>

@interface Pweson : NSObject
@property(nonatomic,copy)NSString * name;
@property(nonatomic)NSInteger age;

-(id)initWithDictionary:(NSDictionary *)dic;
@end

———————————————————————————————————————————————(.m文件)



#import "Pweson.h"

@implementation Pweson
-(id)initWithDictionary:(NSDictionary *)dic{
    self = [super init];
    if (self) {
        [self setValuesForKeysWithDictionary:dic];
    }
    return self;
}
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{
    
}
@end
View Code person 文件
———————————————————————————————————————————————(.h文件)

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@end


———————————————————————————————————————————————(.m文件)

#import "ViewController.h"
#import "Pweson.h"

@interface ViewController ()
@property(nonatomic,copy)Pweson * person;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor lightGrayColor];
    NSDictionary * dic = @{@"name":@"张华",@"age":@45};
    _person = [[Pweson alloc] initWithDictionary:dic];
    [self.person addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
    UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(80, 100, 180, 30)];
    label.textAlignment = NSTextAlignmentCenter;
    label.text = _person.name;
    [self.view addSubview:label];
    [label release];
    
    UILabel * agelabel = [[UILabel alloc] initWithFrame:CGRectMake(280, 100, 60, 30)];
    agelabel.tag = 101;
    agelabel.backgroundColor = [UIColor redColor];
    agelabel.textAlignment = NSTextAlignmentCenter;
    agelabel.text = [NSString stringWithFormat:@"%ld",self.person.age];
    [self.view addSubview:agelabel];
    [agelabel release];
    
    UIButton * but = [UIButton buttonWithType:UIButtonTypeSystem];
    but.frame = CGRectMake(100, 350, 80, 50);
    but.tintColor = [UIColor blueColor];
    [but setTitle:@"增加1岁" forState:UIControlStateNormal];
    [but addTarget:self action:@selector(addAge:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:but];
    [but release];

}
-(void)addAge:(UIButton *)sender{
    self.person.age += 1;
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    if ([keyPath isEqualToString:@"age"]) {
        ((UILabel *)[self.view viewWithTag:101]).text = [NSString stringWithFormat:@"%ld",self.person.age];
    }
}
View Code ViewController 文件
原文地址:https://www.cnblogs.com/benpaobadaniu/p/4852457.html