35 KVC
KVC(key-value-coding)能够让程序通过名称直接存取属性。因为与KVC有关的方法都是在NSObject中定义的,所以凡是继承自NSObject的类都具备KVC功能。
[a setProductName:@"Washing Machine"]
//用KVC重写
[a setvalue:@"Washing Machine" forKey:@"productName"];
这段代码中,setvalue:forKey: 方法会查找名为 setProductName:的存方法(setValue:forKey:方法是在NSObject中定义的)。如果对象a没有setProductName:方法,就会直接为实例变量赋值。
也可以使用KVC读取实例变量。
BNRAppliance *a = [[BNRAppliance alloc] init];
[a setValue:@"Washing Machine" forKey:@"productName"];
NSLog(@"the product name is %@",[a valueForKey:@"productName"]);
这段代码中,valueforKey: 方法会查找名为 ProductName:的存方法(ValueforKey:方法是在NSObject中定义的)。如果对象a没有ProductName:方法,就会直接返回相应的实例变量。
虽然程序中没有实现针对某一变量的存取方法。但是,通过KVC,一样可以存取这个变量。这明显违背了对象封装理念。所谓的对象封装是指对象的方法可以公开,但是实例变量应该保持私有。KVC是一个例外。
非对象类型
KVC只对对象类型有效,但是有些属性的类型并不是对象,例如int或float。如何通过KVC存取这些类型呢?可以使用NSNumber对象。
[a setValue:[NSNumber numberWithInt:240] forKey@"voltag"];
key路径
大部分应用都会有一个相对比较复杂的对象表。例如,可能有一个BNRDepartment对象。它有一个manager属性,它是一个指向BNREmployee对象的指针,而BNREmployee对象则有一个emergencyContact属性,它是一个指向BNRPerson对象的指针,而BNRPerson对象则有一个phoneNumber属性。如果想要销售部经理紧急联系方式的手机号,就可以使用KVC来一次性遍历这些关系:
BNRDepartment *sales = ...;
BNREmployee *sickEmployee = [sales valueForKey:@"manager"];
BNRPerson *personToCall = [sickEmployee valueForKey:@"emergencyContack"];
NSString *numberToDial = [personToCall valueForKey:@"phoneNumber"];
然而,还有一个更简单的方法,就是使用key路径。可以让系统帮你便利这些关系。将你想要的key排成一个长传,以点分隔,注意顺序很重要,第一个想要遍历的对象放在第一个
BNRDepartment *sales = ...;
NSString *numberToDial = [sales valueForKeyPath:@"manager.emergencyContact.phoneNumber"];
网友评论