避免动态绑定的唯一办法就是取得方法的地址,并且直接像函数一样调用它。当一个方法会被连续调用很多的时候,而且您希望节省每次调用方法都要发送消息的开销时,使用方法地址来调用方法就显得很有效。
利用 NSObject
类中的 methodForSelector:
方法,您可以获得一个指向方法实现的指针,并可以 使用该指针直接调用方法实现。methodForSelector:
返回的指针和赋值的变量类型必须完全一致, 包括方法的参数类型和返回值类型都在类型识别的考虑范围中。
下面的例子展示了怎么使用指针来调用setFilled:
的方法实现:
- 首先我们声明一个
setFilled:
方法,具体实现如下:
- (void)setFilled:(int)i {
NSLog(@"%@", [@(i) stringValue]);
}
- 然后我们在需要的地方获取这个方法的函数指针。
void (*filled)(id, SEL, int) = (void (*)(id, SEL, int))[self methodForSelector:@selector(setFilled:)];
- 调用
for (int i = 0; i < 100; i++) {
filled(self, @selector(setFilled:), i);
}
如果该方法是无参无返回值的那么直接调用即可。
IMP filled = [self methodForSelector:@selector(setFilled)];
filled();
方法指针的第一个参数是接收消息的对象(self)
,第二个参数是方法选标(_cmd)
。这两个参数在方 法中是隐藏参数,但使用函数的形式来调用方法时必须显示的给出。
使用methodForSelector:
来避免动态绑定将减少大部分消息的开销,但是这只有在指定的消息被重 复发送很多次时才有意义,例如上面的 for 循环。
注意,methodForSelector:
是 Cocoa 运行时系统的提供的功能,而不是 Objective-C 语言本身的功能。