键值编码
一 使用原则:
1. 值不能为常规类型,建可以是
2. 当键是常规类型时,需要将值包装,系统将自动转换。然而,不支持nil,需要在- (void)setNilValueForKey:(NSString *)theKey中进行处理。(可以自己包装0嘛)
3. 对于不存在的键,会调用函数setValue:forUndefinedKey:/valueForUndefinedKey:
二 键值访问 注意KEY的大小写
常规访问
-<key>
-is<Key> //for bool value
set<Key>
************* 以下为一种约定,方法自己实现 ************
对多访问-有序
Getter Indexed Accessors
-countOf<Key>
-objectIn<Key>AtIndex: or -<key>AtIndexes:
-get<Key>:range://这里是void返回类型,第一个参数是二级指针
Mutable Indexed Accessors
-insertObject:in<Key>AtIndex: or -insert<Key>:atIndexes:
-removeObjectFrom<Key>AtIndex: or -remove<Key>AtIndexes:
-replaceObjectIn<Key>AtIndex:withObject: or-replace<Key>AtIndexes:with<Key>:
对多访问-无序
Getter Unordered Accessors
-countOf<Key>
-enumeratorOf<Key>.
-memberOf<Key>:
Mutable Unordered Accessors
-add<Key>Object: or -add<Key>:
-remove<Key>Object: or -remove<Key>:
-intersect<Key>:
***************************** END ***************************
三 键值验证(约定)
注意: 验证不会自动生效,但是可以通过绑定实现自动验证
validate<Key>:error://-(BOOL)validateName:(id *)ioValueerror:(NSError **)outError
变种的引用:
validateValue:forKey:error:
四 Collection操作//针对数组or Set
简单操作
@avg @max @min @sum //求值 amount为key
//NSNumber*transactionAverage=[transactions valueForKeyPath:"@avg.amount"];
@count 求数量
对象操作
//返回一个该数组下的所有成员的某一key
NSArray *payees=[transactionsvalueForKeyPath:"@distinctUnionOfObjects.payee"];
@distinctUnionOfObjects //清除重复值
@unionOfObjects //保留重复值
集合操作 即嵌套数组
参数同上,换个名字而已
@distinctUnionOfArrays
@unionOfArrays
@distinctUnionOfSets
五 键值编码实现细节
简单属性的访问
默认的 setValue:forKey:
1. 查询set<Key>:.
2. 查询accessInstanceVariablesDirectly返回YES,按顺序查询_<key>,_is<Key>, <key>, oris<Key>
3. 如果匹配,设置.否则,执行setValue:forUndefinedKey:,必须覆盖.
默认的 valueForKey:
1. 查询get<Key>, <key>, or is<Key>,引用,如果为非ID对象,返回包装后的对象
2. 查询countOf<Key>,objectIn<Key>AtIndex:,<key>AtIndexes, //for array
3. countOf<Key>, enumeratorOf<Key>, and memberOf<Key> //for set
4. accessInstanceVariablesDirectly为真,查询_<key>,_is<Key>, <key>, oris<Key>
有序集合的访问
1. 查询insertObject:in<Key>AtIndex: and removeObjectFrom<Key>AtIndex: 或者 insert<Key>:atIndexes: and remove<Key>AtIndexes:
2. set<Key>:
3. _<key> or <key>
唯一有序集合的访问
无序集合的访问
键值观察 KVO
实现:
1. 确定是否有必要
2. addObserver:forKeyPath:options:context:
3. 实现observeValueForKeyPath:ofObject:change:context:
注册
observeValueForKeyPath:ofObject:change:context://注册
removeObserver:forKeyPath://删除
observeValueForKeyPath:ofObject:change:context://响应
再响应方法中,会调用change字典中的值进行必要操作
手动实现
1.
[self willChangeValueForKey:@"openingBalance"];
|
openingBalance=theBalance;//操作
|
[self didChangeValueForKey:@"openingBalance"]; |
2. + (BOOL)automaticallyNotifiesObserversForKey:(NSString*)theKey