KVC访问私有成员

KVC:  key-value coding(键值编码)

它 是一种使用字符串标识符,间接访问对象属性的机制,它是很多技术的基础。主要的方法就两对方法:(setValue:forKey,valueForKey)、setValue:forKeyPath,valueForKeyPath);这个东西有什么作用呢,我先不说原理,先说怎么用,例子如下:

@interface A { NSString* foo; }
 ... // 其它代码
 @end
@interface B { NSString* bar; A* myA; }
 ... // 其它代码
@end
@implementation B
... // 假设 A 类型的对象 a,B 类型的对象b
 A* a = ...;
 B* b = ...;
 NSString* s1 = [a valueForKey:@"foo"]; // 正确
 NSString* s2 = [b valueForKey:@"bar"]; // 正确
 NSString* s3 = [b valueForKey:@"myA"]; // 正确
 NSString* s4 = [b valueForKeyPath:@"myA.foo"]; // 正确
 NSString* s5 = [b valueForKey:@"myA.foo"]; // 错误
 NSString* s6 = [b valueForKeyPath:@"bar"]; // 正确
 ...
@end

其实上面说的那两对方法使用上基本是一样的,只是valueForKeyPath的值是一个路径(路径之间以点号 . 分割),比如数据成员就是对象自己,寻值过程就会向下深入下去。
注意,这里的数据成员的名字都是使用的字符串的形式。这种使用方法的最好的用处在于将数据(名字)绑定到一些触发器(尤其是方法调用)上,
例如键值对观察(Key-Value Observing, KVO)等。

上述代码说明了类的成员变量也可以使用基类NSObject的那两对方法去访问,不一定直接通过类实例访问,但是这种方式还是有一定的风险,具体危险情况请参考这个:http://www.devbean.info/2011/04/from_cpp_to_objc_20/
然后我再说下原理,是俺Copy过来的,大家观赏下:
KVC运用了一个isa- swizzling技术。isa-swizzling就是类型混合指针机制。KVC主要通过isa- swizzling,来实现其内部查找定位的。
isa指针,如其名称所指,(就是is a kind of的意思),指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据。

比如说如下的一行KVC的代码:

[site setValue:@"sitename" forKey:@"name"];
就会被编译器处理成:

SEL sel = sel_get_uid ("setValue:forKey:");
IMP method = objc_msg_lookup (site->isa,sel);
method(site, sel, @"sitename", @"name");
首先介绍两个基本概念:

(1)SEL数据类型:它是编译器运行Objective-C里的方法的环境参数。

(2)IMP数据 类型:他其实就是一个编译器内部实现时候的函数指针。当Objective-C编译器去处理实现一个方法的时候,就会指向一个IMP对象,这个对象是C语言表述的类型(事实上,在Objective-C的编译器处理的时候,基本上都是C语言的)。
这下KVC内部的实现就很清楚的清楚了:一个对象在调用setValue的时候,
(1)首先根据方法名找到运行方法的时候所需要的环境参 数。
(2)他会从自己isa指针结合环境参数,找到具体的方法实现的接口。
(3)再直接查找得来的具体的方法实现。

 

原文链接:http://www.cnblogs.com/jay-dong/archive/2012/12/13/2815778.html 

posted @ 2015-03-24 10:04  妮妮1018  阅读(487)  评论(0编辑  收藏  举报