KVC
KVC类似于.Net或Java中的反射(同样会影响性能),可以用字符串的方式来访问属性的getter和setter。类似javascript中用索引的方式获取属性的值。
KVC的方法定义在NSKeyValueCoding 这个protocol中,NSObject默认已经实现了这个protocol
KVC支持Object 类型(堆)和scalar 类型和struct(栈).非object类型的值作为参数或者返回值的时候,会自动被包装成NSNumber类型或NSValue类型或者被解包装(类似.net中的装箱和拆箱)
一个key是一个字符串,用来标识一个属性或者字段。key必须用ASCII编码,小写字母开头,不能包含空格
一个key path是用key组合起来的字符串,每个key用.分隔。比如这个key path:address.street 用来获取对象的address属性,然后获取address属性的street属性
valueForKey: 方法用来获取一个key对应的getter或字段,如果该类中没有定义这个key对应的getter或字段,那么该类对象会调用valueForUnderfinedKey:方法,该方法默认情况是抛出一个NSUndefineKeyException。valueForUndefinedKey方法可以被重写。
dictionaryWithValuesForKeys:方法用来获取一个NSDictionary,包含了当前对象定义的所有的key和对应的value
setValue:forKey:方法用来给一个属性赋值,该方法默认会把NSValue类型转换成scalars或者structs(拆箱)。如果类中没有定义key对应的成员,那么该类对象调用setValue:forUndefinedKey:抛出一个NSUndefinedException。setValue:forUndefinedKey:可以被重写
setValue:forKeyPath: 根据keypath给一个属性赋值
setValuesForKeysWithDictionary: 给字典中的每一个key对应的属性赋值。遍历字典中的key-value pair,调用setValue:forKey:方法
对于集合类型的属性,如NSArray,NSSet,NSDictionary,成员中不能包含nil。应该用NSNull来代替nil。dictionaryWithValuesForKeys:和setValuesForKeyWithDictionary:这两个方法会自动对NSNull和nil做转换
如果试图给一个非object类型(栈)的属性赋一个nil值,难么对象会调用setNilValueForKey:方法,该方法默认抛出NSInvalidArgumentException。setNilValueForKey:可以被重写
valueForKey: 和setValue:forKey:会调用属性的getter和setter。因此getter的命名规则为-<key>,setter的命名规则为-set<Key>。例如一个NSString *类型的属性“nothin”,那么getter应该定义为:- (NSString *)nothin,setter应该定义为 - (void)setNothin:(NSString *)val
用KVC方式访问有序集合类型的属性,需要实现以下方法:
- countof<Key>
- objectIn<Key>AtIndex: 或者 - <key>AtIndexes:
- get<Key>:range:
用KVC方式访问可变有序集合类型的属性,需要实现以下方法:
- insertObject:in<Key>AtIndex: 或者 - insert<Key>:atIndexes:
- removeObjectFrom<Key>AtIndex: 或者 - remove<Key>AtIndexes:
- replaceObjectIn<Key>AtIndex:withObject: 或者 - replace<Key>AtIndexes:with<Key>:
用KVC方式访问无序集合类型(如NSSet)的属性,需要实现以下方法:
- countOf<Key>
- enumeratorOf<Key>
- memberOf<Key>
用KVC方式访问无序可变集合类型(如NSMutableSet)的属性,需要实现以下方法:
- add<Key>Object: 或者 - add<Key>:
- remove<Key>Object: 或者 - remove<Key>:
- insersect<Key>:
KVC提供了用来验证value的API,用来检查接收到的value是否合法。验证方法的命名规则 validate<Key>:error:
例如
- (BOOL) validNothin: (id *)val error:(NSError * __autoreleasing *)outError{
//Implementation specific code.
return ...;
}
valid方法可能有3种返回值:
1.如果value合法,返回YES
2.如果value非法,给NSError类型的参数赋一个值,返回NO
3.给value赋一个新的合法的值,返回YES
集合操作符用于根据一个keypath获取一个集合,然后用一个操作符来操作这个集合,格式
keypathToCollection.@collectionOperator.keypathToProperty
查询的返回结果类型依赖于以下操作符:
simple collection operators 返回 strings,numbers,或者dates
object operators 返回 NSArray
array and set operators 返回一个array 或 set
simple collection operators
@avg @count @max @min @sum
object operators
@distinctUnionOfObjects @unionOfObjects
array and set operators
@distinctUnionOfArrays
@unionOfArrays
@distinctUnionOfSets