Obective-C通過消息(Message)發送給消息接收對象(receiving object)來調用方法(Method),消息直到運行時纔會綁定方法。
消息發送轉化爲objc_msgSend函數調用:
1、首先找到方法實現程序位置
2、然後把方法實現程序位置和方法參數傳遞給消息接收對象執行
3、返回值(return value)
消息發送過程:
1、首先檢查消息接收對象的緩存
2、然後檢查消息接收對象的分發表(dispatch table)
3、最後通過isa指針找到父類(super class),重複1和2步驟直到找到方法位置或者到達根類(root class)
通過方法地址繞過動態綁定直接調用方法:
- (void)callMethodByAddress {// 通過方法地址調用
void (*setter)(id, SEL, BOOL);// 方法Method定義,id是消息接收者,SEL是方法selector,BOOL方法參數
setter = (void(*)(id, SEL, BOOL))[self methodForSelector:@selector(setFilled:)];// 獲得方法地址
NSDate *start = [NSDate date];
for (int i=0; i<100000; i++) {
setter(self, @selector(setFilled:), YES);// 直接地址調用
}
NSLog(@"%f", [[NSDate date] timeIntervalSinceDate:start]);
start = [NSDate date];
for (int i=0; i<100000; i++) {
[self setFilled:YES];// 消息發送
}
NSLog(@"%f", [[NSDate date] timeIntervalSinceDate:start]);
}
查看打印時間,直接地址調用運行時間的確優於消息發送。
參考: