KVC、KVO

作者: zhouluyao | 来源:发表于2018-07-29 18:23 被阅读9次

KVC最常见的两种应用

1.字典转模型

2.对私有属性赋值

//KVC的应用:字典转模型
- (instancetype)initWithDict:(NSDictionary *)dict
{

   if (self = [super init]) {

        [self setValuesForKeysWithDictionary:dict];

    }
    returnself;
}
//KVC的应用:对私有属性赋值
#import "Person.h"
@implementation Person
{
  NSInteger _height;
}

[p setValue:@181 forKey:@"height"];

accessInstanceVariablesDirectly

Returns a Boolean value that indicates whether the key-value coding methods should access the corresponding instance variable directly on finding no accessor method for a property.

是否在找不到在访问属性方法时,直接访问成员变量.

valueForKey:的原理

valueForKey.png

setValue:forKey:的原理

setValue.png

KVO的全称是Key-Value Observing,俗称“键值监听”,可以用于监听某个对象属性值的改变

当一个类的属性被观察的时候,系统会通过runtime动态的创建一个该类的派生类,并且会在这个类中重写基类被观察的属性的setter方法,而且系统将这个类的isa指针指向了派生类,从而实现了给监听的属性赋值时调用的是派生类的setter方法。重写的setter方法会在调用原setter方法前后,通知观察对象值得改变。

使用了KVO监听的对象

KVO.png

_NSSetValueAndNotify的内部实现

1.调用willChangeValueForKey:

2.调用原来的setter实现

3.调用didChangeValueForKey:

//didChangeValueForKey:内部会调用observer的observeValueForKeyPath:ofObject:change:context:方法

// 给person1对象添加KVO监听
NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
[self.person1 addObserver:self forKeyPath:@"age" options:options context:@"123"];
// 伪代码

- (void)setAge:(int)age
{
    _NSSetIntValueAndNotify();
}

void _NSSetIntValueAndNotify()
{
   [self willChangeValueForKey:@"age"];
   [super setAge:age];
   [self didChangeValueForKey:@"age"];
}

- (void)didChangeValueForKey:(NSString *)key
{
  // 通知监听器,某某属性值发生了改变
   [oberser observeValueForKeyPath:key ofObject:self change:nil context:nil];
}

相关文章

网友评论

      本文标题:KVC、KVO

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