Messaging

编译器将 [receiver message] 编译成:objc_msgSend(receiver, selector); 若有参数的话则是:objc_msgSend(receiver, selector, arg1, arg2, …)。

在动态绑定时,消息函数作的事情:

1. 根据receiver类,找到selector所指的procedure

2.调用找到的procedure, 并将收到的数据对象和参数传递给它

3.最后,将procedure返回的对象作为自己的对象返回

 

注意:编译器能生成消息函数的调用,但我们不应在代码里直接去调用objc_msgSend.

 

Messging 依赖于编译类时产生的一个数据结构,该结构包含:

1.A pointer to the superclass.

2.A class dispatch table.This table has entries that associate method selectors with the class-specific addresses of the mesthod they identify.通过函数名字和函数的地址关联在一起。

当一个新对象被创建,内存分配好,变量初始化好后,就会有一个叫 isa 的指针指向该类的类数据结构。通过isa, 就能访问该类以及通过该类访问他的父类。

当调用一个method 时,先查当前类的dispatch table, 没有查到则查父类的,依此直到NSObject。

 

Using Hidden Arguments

当运行时系统调用objc_msgSend时,还会传递两个隐含的参数:

1.The receiving object. -->self

2.The selector for the method.  -->_cmd

 

- strange

{

id target = getTheReceiver();

SEL method = getTheMethod();

if( target == self || method == _cmd)

     return nil;

return [target performSelector:method];

}

 

 

Getting a Method Address

在循环调用同一个函数多次时,为提高效率,也可以同NSObject的methodForSelector: 直接获得函数的调用地址进行调用。

void (*setter) (id, SEL, BOOL);

int i;

 

setter = (void (*)(id, SEL, BOOL))[target methodForSelector:@selector(setFiled:)];

for( i=0; i<100; i++){

setter(targetList[i], @selector(setFiled:), YES);

}

The first two arguments passed to the procedure are the receving object(self) and the method selector(_cmd).

 

methodForSelector: 是由Cocoa runtime system 提供的。

posted @ 2012-06-04 16:34  agefisher  阅读(236)  评论(0编辑  收藏  举报