美文网首页
添加观察者 (KVO) 键值编码(KVC)

添加观察者 (KVO) 键值编码(KVC)

作者: 努力奔跑的小男孩 | 来源:发表于2017-04-06 23:39 被阅读14次

    KVO 是 Key-Value Observer 键值观察

    参数介绍: self.myLabel 被监听对象
    Observer: 监听的属性值发生变化时,被通知的对象
    forKeyPath:被监听的属性
    option:观察情况的设置,NSKeyValueObservingOptionNew 回调的方法中给的信息,只有新值 NSKeyValueObservingOptionOld 回调方法中携带旧值
    context:上下文

    [self.myLabel addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
    
    当监听的对象的被监听属性,发生变化时会调用这个方法,KVO的回调方法
    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
    {
        //keyPath:被监听的属性
        //object:被监听的对象
        //change:发生改变的信息
        //context 上下文
        if ([keyPath isEqualToString:@"text"]) {
            NSLog(@"%@",change);
            NSLog(@"old = %@",change[@"old"]);
        }
    }
    
    点击按钮是触发方法
    - (IBAction)addCount:(id)sender
    {
        self.myLabel.text = [NSString stringWithFormat:@"点击%ld次",++_count];
    }
    

    KVC

    首先创建两个类(PersonModelDogModel),里面的代码如下:

    DogModel.h文件

    #import <Foundation/Foundation.h>
    
    @interface DogModel : NSObject
    /**
     狗名
     */
    @property (nonatomic, strong) NSString * dogName;
    @end
    
    

    DogModel.m文件

    #import "DogModel.h"
    
    @implementation DogModel
    
    @end
    

    PersonModel.h文件

    #import <Foundation/Foundation.h>
    @class DogModel;
    @interface PersonModel : NSObject
    
    /**
     人名
     */
    @property (nonatomic, strong) NSString * name;
    /**
     年龄
     */
    @property (nonatomic, assign) NSInteger age;
    
    /**
     人有一条狗
     */
    @property (nonatomic, strong) DogModel * dog;
    - (void)logNum;
    @end
    

    PersonModel.m文件

    #import "PersonModel.h"
    
    @implementation PersonModel{
        NSInteger _num; // 私有属性
    }
    
    - (instancetype)init{
        if (self = [super init]) {
            _num = 9; // 给一个初始值
        }
        return self;
    }
    
    - (void)logNum{
        NSLog(@"personModel->num:%zd",_num);
    }
    
    @end
    

    //1. 简单使用

    PersonModel *personModel = [[PersonModel alloc]init];
    personModel.name = @"梅西";
    [personModel setValue:@"16" forKeyPath:@"age"];
    //[personModel setValue:@"88" forKeyPath:@"num"]; // 使用KVC赋值,如果这个类没有这个属性,则会崩溃
            NSLog(@"personModel->name:%@,personModel->age:%zd",personModel.name,personModel.age);
    

    打印结果

    没有num属性赋值时

    打印结果.png
    num属性赋值时 有num属性.png

    注意:使用setValue: forKeyPath:赋值时,一定确保类拥有这个属性,否则会崩溃

    //2. 综合赋值

    PersonModel *personModel = [[PersonModel alloc]init];
    personModel.dog = [[DogModel alloc]init];
    personModel.name = @"梅西";
    [personModel setValue:@"16" forKeyPath:@"age"];
    [personModel setValue:@"Jack" forKeyPath:@"dog.dogName"]; // 使用forKeyPath: 可以索引给属性赋值
    NSLog(@"personModel->name:%@,personModel->age:%zd,狗名字->dogName:%@",personModel.name,personModel.age,personModel.dog.dogName);
    

    注意:forKeyPath: 和 forKey: 功能是一样的,但是forKeyPath:可以进行索引赋值,所以以后尽量使用forKeyPath:

    综合赋值.png

    //3. 改变一个类的私有属性值(重要)

    PersonModel *personModel = [[PersonModel alloc]init];
    [personModel setValue:@"88" forKeyPath:@"_num"]; // num _num
    [personModel logNum];
    
    改变类的私有属性值.png

    //4. 字典转模型

    //5. 取值操作

    //6. 模型转字典

    PersonModel *personModel = [[PersonModel alloc]init];
    personModel.name = @"梅西";
    [personModel setValue:@"16" forKeyPath:@"age"];
    NSDictionary *dict = [personModel dictionaryWithValuesForKeys:@[@"name",@"age"]];
    NSLog(@"%@",dict);
    

    //7. 取出数组中所有Model的某个属性值

    PersonModel *per1 = [[PersonModel alloc]init];
    per1.name = @"A";
    per1.age = 12;
            
    PersonModel *per2 = [[PersonModel alloc]init];
    per2.name = @"B";
    per2.age = 13;
            
    PersonModel *per3 = [[PersonModel alloc]init];
    per3.name = @"C";
    per3.age = 14;
            
    NSArray *perArr = @[per1,per2,per3];
            
    NSArray *nameArr = [perArr valueForKeyPath:@"name"];
    NSLog(@"nameArr:%@",nameArr);
    
    取出数组中所有Model的某个属性值.png

    相关文章

      网友评论

          本文标题:添加观察者 (KVO) 键值编码(KVC)

          本文链接:https://www.haomeiwen.com/subject/syzemttx.html