关于 KVO 和 KVC 的一些总结 以及使用KVC进行字典和模型的互相转换

一直对KVO 和KVC都是停留在 只是知道的情况,从来没有尝试这在项目中使用,最近准备总结一下,在项目里面简单的使用一下

1、什么是KVO?

KVO其实就是Key-Value-Observer,也就是键值观察者,是基于KVC机制实现的另一种模式。也许有不少同学用过SVPullToRefresh或者MJRefresh刷新组件,都使用了KVO来实现。
看了一下感觉kvo有些地方和通知有一些相同的地方,因此在有时候可以使用KVO来代替通知,


举个栗子,

在当前VC里面,当另外一个dataModel类中的某个属性变化时,我需要即时的得到dataModel变化的信息,并且得到所变化的值,这个时候使用键值观察者模式就非常方便了

下面为dataModel类:

#import <Foundation/Foundation.h>
#import "KVOClass.h"

@interface Student : NSObject

@property(nonatomic) NSString *studentName;
@property (nonatomic) float grade;
@property(nonatomic)KVOClass *kvoClass;

@end

设置一秒之后改变  数据模型中的 属性  studentName的值,

-(void)changename{
    self.studentName =@"学生的名字改为+++老王了";
    
    [selfsetValue:@"学生的名字改为+++老王了"forKey:@"studentName"];
}


VC里面,dataModel类的对象添加一个观察者来检测

这样只要model类属性发生变化,这边既可以得到通知,实现对应的逻辑功能即可,一般做数据的更新比较方便。。。

#import "KVOClass.h"
#import "Student.h"
#import "Teacher.h"

@implementation KVOClass


- (instancetype)init
{
    self = [super init];
    if (self) {
         self.student= [[Student alloc]init];
        self.teacher = [[Teacher alloc]init];
        
        //某一对象本身添加 本类对象 为观察者
        [self addObserver:self   forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:@"name"];
        //某一对象添加本类对象为观察者
        [self.student  addObserver:self    forKeyPath:@"studentName"  options:0|1context:nil];
        
        //某一对象添加其他类对象为观察者
        [self.student   addObserver:self.teacher    forKeyPath:@"studentName"  options:0|1context:nil];
        
    }
    return  self;
}


实现收到通知的方法;哪个类 添加观察者 ,哪个类就负责实现这个方法

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
    if (context == @"name") {
        NSLog(@"%@",self.name);
    }else if ([keyPath isEqualToString:@"studentName"]){//回调方法必须处理,否则会crash掉!!!!!!!
         NSLog(@"本类对象++++%@",self.student.studentName);
    }else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}


下面是在其他类Teacher中处理回调函数的情况

/****

 change  通知回调的参数,包含所检测对象的值的变化  change[@"new"]即可取到

 注意!!!  change[@"new"]取到的值全是对象数据类型,没有基本数据类型的(如果是 int float等,得到的是NSNumber类型)

 同样的  kvc的时候赋值的时候也要是对象类型,基本类型数据要转成对象类型的

 *****/



-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
    if ([keyPath isEqualToString:@"studentName"]) {
        NSLog(@"老师貌似收到了学生信息改变的通知了,+++%@",change[@"new"]);
    }else if ([keyPath isEqualToString:@"grade"]){
      NSLog(@"老师貌似收到了学生信息改变的通知了,+++%@",change[@"new"]);
    }
}


移除观察者, 哪个类 添加观察者 ,哪个类就负责移除观察者

-(void) dealloc
{
    [self removeObserver:self forKeyPath:@"name"];
    [self.student removeObserver:self forKeyPath:@"studentName"];
    [self.student removeObserver:self.teacher forKeyPath:@"studentName"];
    [self.student removeObserver:self.teacher forKeyPath:@"grade"];

}


 

总结一下:

//总结   1、谁成为观察者,谁就要实现收到通知的回调方法,可以在当前类(添加观察者的类),也可以在观察者的类中去实现,

//      2、添加观察者与移除观察者是成对出现的,一定要记得移除,原则是在那个类添加就在那个类移除观察者。否则会crash!!!

//      3、某一对象可以添加当前类的对象为观察者,也可以添加其他类的对象为观察者,

                                                                                                    。                                                                              KVC和字典转模型

http://www.2cto.com/kf/201507/415647.html

http://www.bkjia.com/IOSjc/989396.html

 //******************  使用 KVC 自动字典转模型 ******************//
    NSDictionary *dic = @{@"name":@"cheng",@"nick":@"laocheng",@"addr":@"henan",@"phone":@(10086),@"test":@"false"};

    Student *student = [[Student alloc]init];
    [student setValuesForKeysWithDictionary:dic];   // 使用 KVC 自动字典转模型,实体类只有声明一下属性,此方法可以自动把字典的key
                                                    //和value 分别赋给 实体
//    /如果kvc转模型的时候 传的字典里面的key如果没有对应属性的key时,会自动调用此方法
//    -(void)setValue:(id)value forUndefinedKey:(NSString *)key{
    NSLog(@"phone : %@",student.phone);
    
     //******************  使用 KVC 自动模型转字典 ******************//
    NSDictionary *dict = [student dictionaryWithValuesForKeys:@[@"name",@"nick",@"addr",@"phone"]];
    NSLog(@"dict : %@",dict);

数据模型

@interface Student : NSObject
@property(nonatomic)NSString *name;
@property(nonatomic)NSString *nick;
@property(nonatomic)NSString *addr;
@property(nonatomic)NSNumber *phone;
@property(nonatomic)NSString *testProperty;

@end


 

                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值