第一步、消息發(fā)送
#import <objc/message.h>
// 創(chuàng)建person對象
person *p = [[person alloc] init];
// 調(diào)用對象方法
[p eat];
// 本質(zhì):讓對象發(fā)送消息(對象方法)
objc_msgSend(p, @selector(eat));
// 本質(zhì):讓類對象發(fā)送消息(類方法)
objc_msgSend([person class], @selector(sleep));
第二步、動(dòng)態(tài)解析
第三步、消息重定向

屏幕快照 2020-07-27 上午11.37.52.png
- (void)viewDidLoad {
[super viewDidLoad];
[self performSelector:@selector(eat)];
}
/***第一次、動(dòng)態(tài)解析***/
+(BOOL)resolveInstanceMethod:(SEL)sel
{
if (sel == @selector(eat)) {
class_addMethod([self class], sel, (IMP)funMethod, "v@:");
}
return YES;
}
void funMethod(id obj,SEL _cmd) {
NSLog(@"funMethod"); //新的 fun 函數(shù)
}
/***第二次、接受者消息重定向***/
- (id)forwardingTargetForSelector:(SEL) aSelector
{
if (aSelector == @selector(eat)) {
person * p = [[person alloc]init];
return p;
}
return nil;
}
/***第三次、獲取函數(shù)的參數(shù)和返回值類型,返回簽名***/
- (NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector {
if ([NSStringFromSelector(aSelector) isEqualToString:@"eat"]) {
return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}
return [super methodSignatureForSelector:aSelector];
}
/***第三次、消息重定向***/
- (void)forwardInvocation:(NSInvocation*)anInvocation {
SEL sel = anInvocation.selector; // 從 anInvocation 中獲取消息
person * p = [[person alloc]init];
if([p respondsToSelector:sel]) { // 判斷 Person 對象方法是否可以響應(yīng) sel
[anInvocation invokeWithTarget:p]; // 若可以響應(yīng),則將消息轉(zhuǎn)發(fā)給其他對象處理
}else{
[self doesNotRecognizeSelector:sel]; // 若仍然無法響應(yīng),則報(bào)錯(cuò):找不到響應(yīng)方法
}
}
@end