KVO与KVC简单理解

KVO与KVC简单理解

///////////////////////////////////////我是该死的分割线/////////////////////////

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

系统框架已经支持KVO,所以我们要做的就是如何用了.

1. 注册,指定被观察者的属性,//谁要观察,谁的属性改变通知你.

[stockForKVO addObserver:self forKeyPath:@"price" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];

//对象  添加观察者:我自己 哪个属性:price属性 可选项:模式|模式  上下文:空

这样就把注册,指定观察者属性都做完了

2. 实现回调方法//通知了你,你得做点事吧.

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context

{

if([keyPath isEqualToString:@"price"])

{

myLabel.text = [stockForKVO valueForKey:@"price"];

}

}

//在这个方法里写通知你之后干的事,像例子说的那样,先判断是不是这个属性,然后再赋值.判断这一步不能少,如果同时好多人在观察,可能搞混淆.这里得引入和通知的区别了.

//KVO与通知区别:

通知:是一种广播机制,在实践发生的时候,通过通知中心对象,一个对象能够为所有关心这个时间发生的对象发送消息,两者都是观察者模式,不同在于KVO是被观察者直接发送消息给观察者,是对象间的直接交互,通知则是两者都和通知中心对象交互,对象之间不知道彼此

KVO使用:被观察着发生addobserver:forkeyPath:options:context:方法来添加观察者.然后只要被观察者的keypath值发生变化(注意单纯改变值不会调用此方法,只有通过getter和sett来改变值才会触发KVO),就会在观察者里调用方法observerValueForKeyPath:ofobject:change:context:因此实现此方法来对KVO发出的通知做出响应.

这些代码都是秩序在观察者里进行实现,被观察者不用添加任何代码,所以谁要监听谁要注册,然后对响应进行处理即可,使得观察者与被观察者完全解耦,运用很灵活很简便,但是KVO只能检测类中属性,并且属性名都是通过NSString来查找,编译器不会帮你检测对错和补全,纯手敲会比较容易出错

通知的使用:通知的发出是由通知中心来统一发出,而不同通知通过唯一标示名notifcationName来区分,标示名由发送通知的类来起.首先被观察者自己在必要的方法A里,通过方法postNotificationName:object:发出通知notificationName这样发送通知着这边的工作就完成了,每次A被调用,就会发送一次通知notificationName

然后谁要监听A的变化,就通过[NSNotificationCenter defaultCenter] 的方法addobserver:sslector:name:object为观察者注册监听name为notificationNmae的通知.

每次发出name为notificationNmae的通知时,注册监听后的观察着就会调用其自己定义的方法notificationselector来进行相应

NSNotification的特点,就是需要被观察者先主动发出通知,然后观察者注册监听后,再来进行响应,比KVO多了发送通知的一步,但是其优点是监听不局限属性的变化,还可以对多种多样的状态变化进行监听,监听范围广,使用灵活.

3. 移除观察//不会自动移除,需要手动移除

增加观察与取消观察是成对出现的,所以需要在最后的时候,移除观察者

///////////////////////////////////////我是该死的分割线//////////////////////////

KVC是KeyValueCoding的简称,翻译过来是键值编码,它是一种可以直接通过字符串的名字(key)来访问类属性(实例变量)的机制。而不是通过调用Setter、Getter方法(点语法)访问。

当使用KVO、Core Data、CocoaBindings、AppleScript(Mac支持)时,KVC是关键技术。

//

关键方法定义在:NSKeyValueCodingprotocol

The NSKeyValueCoding informal protocol defines a mechanism by which you can access the properties of an object indirectly by name (or key), rather than directly through invocation of an accessor method or as instance variables. Thus, all of an object’s properties can be accessed in a consistent manner.

这个键值编码非正式协议定义了一个机制通过你可以间接的获取一个对象的属性通过名字(或者叫key),而不是直接通过调用访问器方法或者实例变量.因此,一个对象的所有属性可以被存取用一个通用的方式.

The basic methods for accessing an object’s values are setValue:forKey:, which sets the value for the property identified by the specified key, and valueForKey:, which returns the value for the property identified by the specified key. The default implementation uses the accessor methods normally implemented by objects (or to access instance variables directly if need be).

这个基本方法对于访问一个对象的值是 setValue:forKey用来设置值对于可识别的属性通过规定的key,和valueForKey用来返回一个值对于可识别的属性通过规定的key.这个默认的实现使用了访问器方法正常的实现通过对象(或者通过实例变量如果需要的话).

Default Search Pattern for setValue:forKey://默认查找模式对于setValue:forKey

When the default implementation ofsetValue:forKey:is invoked for a property the following search pattern is used:

当这个默认实现setValue:forKey是属性调用模式是使用下列搜索模式

The receiver’s class is searched for an accessor method whose name matches the pattern set:.

接收器的类去搜索访问器方法的名字匹配这个设置模式.

If no accessor is found, and the receiver’s class method accessInstance VariablesDirectlyreturns YES, the receiver is searched for an instance variable whose name matches the pattern, _<key>,_is<key>,<key>,is<key>,in that order.

如果访问器方法没有找到,而且接受方法accessInstance VariablesDirectlyreturns返回yes,接受器将会搜索实例变量的名字匹配,在这种情况下.

If a matching accessor or instance variable is located, it is used to set the value. If necessary, the value is extracted from the object as described inRepresenting Non-Object Values.

如果匹配访问器方法或实例变量都加载了,它通常使用set the value.如果必要的话,值引出从对象像Representing Non-Object Values文档描述的一样.

If no appropriate accessor or instance variable is found,setValue:forUndefinedKey:is invoked for the receiver.

如果都没有找到的话,将会唤醒setValue:forUndefinedKey给接收器.//一般抛出异常,可重写.

//在字典转模型里,服务器返回的数据有些不想要就重写这个方法.

Default Search Pattern for valueForKey://默认搜索模式对于valueForKey

When the default implementation of valueForKey:is invoked on a receiver, the following search pattern is used:

//当默认实现valueForKey是调用在接收器,通常使用以下搜索模式

Searches the class of the receiver for an accessor method whose name matches the pattern get<key>,<key>,is<key>, in that order. If such a method is found it is invoked. If the type of the method's result is an object pointer type the result is simply returned. If the type of the result is one of the scalar types supported by NSNumber conversion is done and an NSNumber is returned. Otherwise, conversion is done and an NSValue is returned. Results of arbitrary types are converted to NSValue objects, not just NSPoint,NSRange,NSRect, and NSSize types).

搜索接受者类从访问器方法的名字匹配参数get<key>,<key>,is<key>,在那种情况下.如果发现这个方法被调用了,如果这个方法飞返回类型是一个对象指针类型,这个结果简单的返回.如果这个结果类型是数量的一种,将转换为NSNumber返回,否则,转换NSValue返回.任意的结果类型都是转换成NSValue类了,不只是NSPoint,NSRange,NSRect, and NSSize types.

Otherwise (no simple accessor method is found), searches the class of the receiver for methods whose names match the patterns countOf and objectInAtIndex:(corresponding to the primitive methods defined by the NSArray class) andAtIndexes:(corresponding to the NSArray  method  objectsAtIndexes:). If the countOf method and at least one of the other two possible methods are found, a collection proxy object that responds to all NSArray methods is returned. Each NSArray message sent to the collection proxy object will result in some combination of countOf,objectInAtIndex:, andAtIndexes:messages being sent to the original receiver of valueForKey:. If the class of the receiver also implements an optional method whose name matches the pattern get:range:that method will be used when appropriate for best performance.

否则(没有找到简单访问器方法),搜索这个接受器的类从方法匹配参数countOfand objectInAtIndex(相当于去用原始方法定义在NSArray 类里)andAtIndexes(相当于去用这个NSArray方法 andAtIndexes).如果countOf方法至少一到两个可能的方法被找到,一个集合代理对象对于所有的NSArray methods将会被返回,每一个NSArray 消息发送给集合代理对象将会返回countOf,objectInAtIndex,andAtIndexes组合.消息将要发送给valueForKey的原始接受者,如果这个接受者的类也实现一个可选方法,是名字匹配参数get:range:,那方法将会使用当合适为了做好的执行.

Otherwise (no simple accessor method or set of array access methods is found), searches the class of the receiver for a threesome of methods whose names match the patterns countOf,enumeratorOf, and memberOf:(corresponding to the primitive methods defined by theNSSet class). If all three methods are found, a collection proxy object that responds to all NSSet methods is returned. Each NSSet message sent to the collection proxy object will result in some combination of countOf,enumeratorOf, and memberOf:messages being sent to the original receiver of valueForKey:.

否则(访问器方法和set of array access methods都没有找到),搜索接收器的类将从一个三人组方法,是名字匹配模式countOf,enumeratorOf, and memberOf(相当于使用原始方法定义在NSSet类里),如果都三个方法都找到了,一个集合代理对象将会响应所有的NSSet方法并返回.每一个NSSet 消息发送给集合代理对象将会生成countOf,enumeratorOf, andmemberOf组合,消息将会被发送去这的valueForKey原始接受器.

Otherwise (no simple accessor method or set of collection access methods is found), if the receiver's class method accessInstanceVariablesDirectly returnsYES, the class of the receiver is searched for an instance variable whose name matches the pattern_,_is,, oris, in that order. If such an instance variable is found, the value of the instance variable in the receiver is returned. If the type of the result is one of the scalar types supported by NSNumber conversion is done and an NSNumber is returned. Otherwise, conversion is done and an NSValue is returned. Results of arbitrary types are converted toNSValueobjects, not justNSPoint,NSRange,NSRect, andNSSizetypes.

否则(没有找到简单访问器方法和set of collection access methods的一种),如果接收器的类方法

accessInstanceVariablesDirectly返回yes,这个接收器的类将会搜索实例变量,是名字匹配参数

_<key>,_is<key>,<key>,is<key>,在这种情况下.如果找到了实例变量,这个实例变量的值将会被返回.如果结果的类型是数量类型的一种,将转换成NSNumber并返回,否则,转换为NSValue返回.任意的结果类型都是转换成NSValue类了,不只是NSPoint,NSRange,NSRect, and NSSize types.

If none of the above situations occurs, returns a result the default implementation invokes valueForUndefinedKey:.

如果没有出现上述情况,返回默认实现结果调用valueForUndefinedKey.

KVC支持类对象和内建基本数据类型。

获取值

valueForKey:,传入NSString属性的名字。

valueForKeyPath:,传入NSString属性的路径,xx.xx形式。

valueForUndefinedKey它的默认实现是抛出异常,可以重写这个函数做错误处理。

修改值

setValue:forKey:

setValue:forKeyPath:

setValue:forUndefinedKey:

setNilValueForKey:当对非类对象属性设置nil时,调用,默认抛出异常。

一对多关系成员的情况

mutableArrayValueForKey:有序一对多关系成员  NSArray

mutableSetValueForKey:无序一对多关系成员  NSSet

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

推荐阅读更多精彩内容