for ( i = 0; i < 1000, i++ )
setter(targetList[i], @selector(setFilled:), YES);
方法指针的第一个参数是接收消息的对象(self),第二个参数是方法选标(_cmd)。这
两个参数在方法中是隐藏参数,但使用函数的形式来调用方法时必须显示的给出。
使用 methodForSelector:来避免动态绑定将减少大部分消息的开销,但是这只有在指定
的消息被重复发送很多次时才有意义,例如上面的 for 循环。
注意:methodForSelector:是 Cocoa 运行时系统的提供的功能,而不是 Objective-C
语言本身的功能。
5.2、objc_msgSend 函数
在 Objective-C 中,消息是直到运行的时候才和方法实现绑定的。编译器会把一个消
息表达式:
[receiver message]
转换成一个对消息函数 objc_msgSend 的调用。该函数有两个主要参数:消息接收
者和消息对应的方法名字——也就是方法选标:
objc_msgSend(receiver, selector)
同时接收消息中的任意数目的参数:
objc_msgSend(receiver, selector, arg1, arg2, ...)
该消息函数做了动态绑定所需要的一切:
1)它首先找到选标所对应的方法实现。因为不同的类对同一方法可能会有不同的实现,
所以找到的方法实现依赖于消息接收者的类型。
2)然后将消息接收者对象(指向消息接收者对象的指针)以及方法中指定的参数传给找
到的方法实现。
3)最后,将方法实现的返回值作为该函数的返回值返回。
注意:编译器将自动插入调用该消息函数的代码。您无须在代码中显示调用该消息函数。
消息机制的关键在于编译器为类和对象生成的结构。每个类的结构中至少包括两个基本元
素:
1)指向父类的指针。
2 ) 类 的 方 法 表 。 方 法 表 将 方 法 选 标 和 该 类 的 方 法 实 现 的 地 址 关 联 起 来 。 例 如 ,
setOrigin::的方法选标和 setOrigin::的方法实现的地址关联,display 的方法选标和
display 的方法实现的地址关联,等等。
当新的对象被创建时,其内存同时被分配,实例变量也同时被初始化。对象的第一个
实例变量是一个指向该对象的类结构的指针,叫做 isa。通过该指针,对象可以访问它对
应的类以及相应的父类。
注意:尽管严格来说这并不是 Obective-C 语言的一部分,但是在 Objective-C 运行时系
统中对象需要有 isa 指针。对象和结构体 struct objc_object(在 objc/objc.h 中定义)