KVC、KVO 代码记

1. KVC

KVC一种间接更改对象状态的方式,其实现方法是使用字符串来描述对象需要更改的属性。
KVC中的基本调用包括valueForKey:和setValue:ForKey:,以字符串的形式向对象发送消息.

声明两个对象用于测试如下:

@interface Student : NSObject


@property (nonatomic,copy) NSString *name;

@property (nonatomic,assign) int score;

@property (nonatomic,strong) Book *book;

@property (nonatomic,strong) NSArray *stus;


@end
@interface Book : NSObject

@property (nonatomic,copy) NSString *bookname;

@end
以上就是Student Book 两个头文件,由于暂时不需要.m文件里干任何事,所以这就不贴.m代码了

测试代码:

void testKvc(){
    
    /1.kvc 简单用法///
    
    Student *student = [[Student alloc]init];
    
    //kvc 设置值
    [student setValue:@"lk" forKey:@"name"];
    [student setValue:@"90" forKey:@"score"];
    Book *book = [[Book alloc]init];
    book.bookname = @"book-one";
    [student setValue:book forKey:@"book"];
    
    //kvc  取值
    NSLog(@"name:%@",[student valueForKey:@"name"]);
    //name:lk
    NSLog(@"score:%@",[student valueForKey:@"score"]);
    //score:90
    NSLog(@"bookname:%@",[student valueForKeyPath:@"book.bookname"]);
    //bookname:book-one
    
    /2. kvc 批量设置值///
    
    Student *stu = [[Student alloc]init];
    
    NSArray *keys = [NSArray arrayWithObjects:@"name",@"score", nil];
    NSArray *values = [NSArray arrayWithObjects:@"student-lk",[NSNumber numberWithInt:100], nil];
    NSDictionary *dict = [NSDictionary dictionaryWithObjects:values forKeys:keys];
    //批量设置值
    [stu setValuesForKeysWithDictionary:dict];
    NSLog(@"name:%@",[stu valueForKey:@"name"]);
    //name:student-lk
    NSLog(@"score:%@",[stu valueForKey:@"score"]);
    //score:100
    //批量获取值
    NSLog(@"values:%@",[stu dictionaryWithValuesForKeys:keys]);
    //values:{
    //    name = "student-lk";
    //    score = 100;
    //}

    /3.对数组的操作///

    
    Student *s1 = [[Student alloc]init];
    s1.name = @"student-01";
    s1.score = 90;
    
    Student *s2 = [[Student alloc]init];
    s2.name = @"student-02";
    s2.score = 85;
    
    Student *s3 = [[Student alloc]init];
    s3.name = @"student-03";
    s3.score = 76;
    
    [s3 setValue:@[s1,s2,s3] forKey:@"stus"];
    NSLog(@"s3 count:%lu",s3.stus.count);
    //s3 count:3
    NSLog(@"s3 count-2:%@",[s3 valueForKeyPath:@"stus.@count"]);
    //s3 count-2:3
    NSLog(@"max score:%@",[s3 valueForKeyPath:@"stus.@max.score"]);
    //max score:90
    NSLog(@"avg score:%@",[s3 valueForKeyPath:@"stus.@avg.score"]);
    //avg score:83.666666666666666666666666666666666666
    
}

KVC赋值查找方式,

[student setValue:@"lk"forKey:@"name"];

以这为例子,
KVC 在setValue:ForKey时会先查找其setter方法, 如果不存在setter方法,就在类中查找名为name或者_name的实例变量,然后为它赋值。

2. KVO

KVO是一种非常重要的机制, 主要用于监听对象的属性的变化.

在刚刚的Student.h文件添加一个监听对象

@interface Student : NSObject


@property (nonatomic,copy) NSString *name;

@property (nonatomic,assign) int score;

@property (nonatomic,strong) Book *book;

@property (nonatomic,strong) NSArray *stus;


@end

#pragma kvo
@interface StudentObserver : NSObject

@end

.m文件如下:

@implementation Student


@end

@implementation StudentObserver


/**
 * keyPath 被监听的key 值
 * object 被监听的对象
 * change存放着新旧值,取决于外面监听方法options 的设置
 * context 外面存放过来的值
 *
 **/
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{

    NSLog(@"%@",keyPath);
    //name
    NSLog(@"%@",object);
    // <Student: 0x1002033d0>
    NSLog(@"%@",change);
    //{
      //  kind = 1;
        //new = "student-change";
        //old = "student-01";
    //}
    NSLog(@"%@",context);
    //params

}

测试方法(执行结果在.m中已经写出来了,这里主要看下测试的代码):
void testKvo(){
    
    Student *student = [[Student alloc]init];
    student.name = @"student-01";
    student.score = 98;

    //监听
    StudentObserver *stuObserver = [[StudentObserver alloc]init];
    //observer 哪个对象用于其监听
    //keyPath  被监听的的key值
    //options 枚举类型,根据其设置监听对象方法字典里存放啥值
    //context 该参数设置的值会传到监听StudentObserver 监听方法里
    [student addObserver:stuObserver forKeyPath:@"name" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:@"params"];
    
    //改变name值,查看控制台输出
    student.name = @"student-change";
    
    //移除
    [student removeObserver:stuObserver forKeyPath:@"name"];
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值