IOS KVC,KVO

KVC

KVC是key Value Coding的缩写,主要方法有setValue:forKey和valueForKey:。

setValue:forKey:主要是赋值。value参数是值,key参数是变量名。

eg:[student setValue:@”张3”forKey:@”name”];

给student的name属性赋值为张3 。

valueForKey: 主要是取值。key是变量名,方法返回变量的值。

setValue:forKeyPath:可以通过“.”的方式,给私有的自定义类型的私有变量赋值。

eg:[student setValue:@”LI4” forKeyPath:@”person.name”];

利用KVC机制,可以给继承于NSObject类的私有变量赋值。

注意:

key里面的属性,是什么类型,value对应的就应该是什么类型。

key里面的属性,一定要是类的属性,否则会报错。

主要用在多个类,对象嵌套的时候。

譬如:

我们有一个人 这个人有一个手机类 这个手机类 有一个电池类 我们要获取这个电池类 比之前复杂了吧。

没有KVC

Persion *persion =[ [Persion alloc] init ];

Phone *phone = persion.phone;

Battery *battery = phone.battery;

一:使用KVC

Battery *battery = [persion valueForKeyPath: @"phone.battery" ];

注意- valueForKeyPath 里面的值是区分大小写的,你如果写出Phone.Battery 是不行的.

KVC 最常用的还是在序列化和反序列话对象。我们经常需要把json字符串反序列化成我们想要的对象 下面是一个例子 将字典用NSKeyedArchiver 序列化成对象

- (id)initWithDictionary:(NSDictionary *)dictionary {

self = [self init];

if (self){

[self setValuesForKeysWithDictionary:dictionary];

}

return self;

}

注意 这里有一个坑 当我们setValue 给一个没有定义的字典值(forUndefinedKey)时 会抛出NSUndefinedKeyException异常的 记的处理此种情况.

还有一个需要注意的是KVC 并没有类型检验,毕竟Object-C 还是动态的啦。 还是看下面的代码吧

[persion setValue:[NSNumber numberWithInteger:1] forKey:@"name"];

// compiles and runs

persion.name = [NSNumber numberWithInteger:1];

// won't compile: Incompatible pointer types assigning to 'NSString *' from 'NSNumber *'

setValue forKey 得到的对象是泛型的id, 只有在使用的时候才能确定类型。你可能会问不至于吧 OC 这样弱啊,当然不是 OC 提供了了一个方法validateValue来解决这个问题

@property (nonatomic, strong) NSString name;

- (BOOL)validateName:(id*)ioValue error:(NSError**)error {

// Validation logic goes here

}

Person *p = [Person new];

NSString *name = @"Jason Hu";

NSError *error = nil;

// This call below actually calls our validateName: error: method

if ([p validateValue:&name forKey:@"name" error:&error]) {

[p setValue:name forKey:@"name"];

}

你可能会问写这样多代码 才只验证了一个属性 那如果我这个类有n+个属性 难道我要写n+个验证方法吗?

二:KVC 验证

到这里我们对KVC已经有了一个初步印象,到这里其实还只是冰山一角。

下面我们要提高更高的要求,如果让key 支持 不区分大小写

下面我们提到一个方法initialize

initialize是在类或者其子类的第一个方法被调用前调用。所以如果类没有被引用进项目或者类文件被引用进来,但是没有使用,那么initialize也不会被调用 ,到这里 知道我们接下来要干嘛了吧

+ (void)initialize {

[super initialize];

dispatch_once(&onceToken, ^{

modelProperties = [NSMutableDictionary dictionary];

propertyTypesArray = @[/* removed for brevity */];

});

NSMutableDictionary *translateNameDict = [NSMutableDictionary dictionary];

[self hydrateModelProperties:[self class] translateDictionary:translateNameDict];

[modelProperties setObject:translateNameDict forKey:[self calculateClassName]];

}

+ (void)hydrateModelProperties:(Class)class translateDictionary:(NSMutableDictionary *)translateDictionary {

if (!class || class == [NSObject class]){

return;

}

unsigned int outCount, i;

objc_property_t *properties = class_copyPropertyList(class, &outCount);

for (i = 0; i < outCount; i++){

objc_property_t p = properties[i];

const char *name = property_getName(p);

NSString *nsName = [[NSString alloc] initWithCString:name encoding:NSUTF8StringEncoding];

NSString *lowerCaseName = [nsName lowercaseString];

[translateDictionary setObject:nsName forKey:lowerCaseName];

//注意此处哦

NSString *propertyType = [self getPropertyType:p];

[self addValidatorForProperty:nsName type:propertyType];

}

free(properties);

[self hydrateModelProperties:class_getSuperclass(class) translateDictionary:translateDictionary];

}

KVO

Key-Value Observing (简写为KVO):当指定的对象的属性被修改了,允许对象接受到通知的机制。每次指定的被观察对象的属性被修改的时候,KVO都会自动的去通知相应的观察者,相当于设计模式中的观察者模式。

KVO的优点:

当有属性改变,KVO会提供自动的消息通知。这样的架构有很多好处。首先,开发人员不需要自己去实现这样的方案:每次属性改变了就发送消息通知。这是KVO 机制提供的最大的优点。因为这个方案已经被明确定义,获得框架级支持,可以方便地采用。开发人员不需要添加任何代码,不需要设计自己的观察者模型,直接可 以在工程里使用。其次,KVO的架构非常的强大,可以很容易的支持多个观察者观察同一个属性,以及相关的值。

KVO是Key Value Observer的缩写,主要方法是addObserver:forKeyPath:options:context:和observeValueForPath:ofObject:change:context。

addObserver:forKeyPath:options:context:注册监听事件。

observeValueForPath:ofObject:change:context当注册的值,利用KVC发生改变的时候,就会触发这个方法。

在最后的dealloc方法里面,要记得移除监听事件。

补充:iOS之KVC和KVO

一、KVC(key-value-coding)

1、只针对类属性,设置键值对

2、设置setValue: forKey:,即forKey只能为类属性

3、取值valueForKey

二、KVO(key-value-observing)被观察者的属性发生改变时,通知观察者

1、利用KVC对类属性进行设置

2、注册observing对象addObserver:forKeyPath:options:context:

3、观察者类必须重写方法 observeValueForKeyPath:ofObject:change:context:

4、应用,MVC模型中,数据库(dataModal)发生变化时,引起view改变,用这种方式实现非常方便

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容

  • KCV 其实由于ObjC的语言特性,你根部不必进行任何操作就可以进行属性的动态读写,这种方式就是Key Value...
    TYM阅读 1,047评论 0 4
  • 前言: 本文基本不讲KVC/KVO的用法,只结合网上的资料说说对这种技术的理解。 由于KVO内容较少,而且是以KV...
    土b兰博王阅读 3,040评论 0 33
  • KVC(Key-value coding)键值编码,单看这个名字可能不太好理解。其实翻译一下就很简单了,就是指iO...
    朽木自雕也阅读 1,543评论 6 1
  • 1.KVC底层是通过runtime对method和value操作 比如说如下的一行KVC的代码: [sit set...
    smart_small阅读 785评论 0 0
  • 一、KVC 通过关键字,访问属性及成员变量。1.kvc当调用setValue:属性值 forKey:@”name“...
    doudo阅读 309评论 0 0