kvo、kvc知识点总结

KVC和KVO

一、摘要

*1 KVO,即:Key-Value-Observing,它提供一种机制,当指定的对象的属性被修改后,则观察者就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。

*2 KVC是Key-Value-Coding的简称,它是一种可以直接通过字符串的名字(key)来访问类属性(实例变量)的机制。而不是通过调用Setter、Getter方法访问。当使用KVO、Core Data、CocoaBindings、AppleScript(Mac支持)时,KVC是关键技术。

二、作用

KVC作用一般是两个:字典转模型 和 给私有的成员变量赋值

*1 字典转模型

NSDictionary *dict=@{@"name":@"浩杰",@"age":@"18"};
Person *person=[Person new];
[person setValuesForKeysWithDictionary:dict];
NSLog(@"--%@---%@",person.name,person.age);

注意事项:使用setValuesForKeysWithDictionary的时候,要保证字典的key的数量小于或者等于模型类,且key必须要和模型中的属性名字相同,否则会出现错误。

*2 复杂的字典转模型
如果一个模型类,其中一个属性也是一个模型,这种情况就需要给这个属性传入一个字典

NSDictionary *dict=@{@"name":@"浩杰",@"age":@"18",@"dog":@{@"name":@"tom",@"weight":@"10"}};
Person *person=[Person new];
[person setValuesForKeysWithDictionary:dict];

NSLog(@"----%@",person.dog);
 //    {
 //        name = tom;
 //        weight = 10;
//    }
person.dog=[Dog new]; //必须加这句话,不加之前,查看打印结果会看到person.dog类型是字典;加之后打印结果是Dog
NSLog(@"----%@",person.dog);
//

[person.dog setValuesForKeysWithDictionary:dict[@"dog"]];

注意事项:当给person对象发送setValuesForKeysWithDictionary消息的时候,实际上此时它的dog属性指向一个字典,而不是Dog类的对象

*3 给私有的成员变量赋值

如果是在.h中定义了某个属性,这是暴露给外界,可以被访问(public或者protect类型);如果是在.m中定义了某个属性,用KVC则同样可以进行赋值和取值操作。

Person *person=[Person new];
[person setValue:@"1.85" forKey:@"height"];
NSLog(@"--%@",[person valueForKey:@"height"]);

注意:属性height是在.m文件中定义的; value的值一定是对象,所以即使person的私有成员变量是int类型的,但是setValue的时候要将其赋值为对象类型的。在进行取值的时候也是一样取出对象,使用NSNumber。

KVO 主要用来监听某个对象的某个属性的变化,当发生变化的时候,观察者会调用对应的函数,实现对应的功能

Person *person=[Person new];
[person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];

 //当person的name发生变化的时候,self就会执行下面的函数,在该函数中实现相应功能即可
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
  }

注意事项:

//如果进行了addobserver操作,那么就要进行相应的removeObserver操作。这是因为:addobserver操作,会在通知中心注册监听者(这里是self),当self这个对象销毁后,如果没有removeObserver,那么当属性改变时候,仍然会给self这个已经销毁的对象发送属性改变的消息,因为在通知中心中,已经销毁的对象并没有撤销注册
-(void)dealloc{
[self.person removeObserver:self forKeyPath:@"name"];

}

你可能感兴趣的:(kvo、kvc知识点总结)