第一步、消息发送
#import <objc/message.h>
// 创建person对象
person *p = [[person alloc] init];
// 调用对象方法
[p eat];
// 本质:让对象发送消息(对象方法)
objc_msgSend(p, @selector(eat));
// 本质:让类对象发送消息(类方法)
objc_msgSend([person class], @selector(sleep));
第二步、动态解析
第三步、消息重定向
屏幕快照 2020-07-27 上午11.37.52.png
- (void)viewDidLoad {
[super viewDidLoad];
[self performSelector:@selector(eat)];
}
/***第一次、动态解析***/
+(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 函数
}
/***第二次、接受者消息重定向***/
- (id)forwardingTargetForSelector:(SEL) aSelector
{
// if (aSelector == @selector(eat)) {
// person * p = [[person alloc]init];
// return p;
// }
return nil;
}
/***第三次、获取函数的参数和返回值类型,返回签名***/
- (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 对象方法是否可以响应 sel
[anInvocation invokeWithTarget:p]; // 若可以响应,则将消息转发给其他对象处理
}else{
[self doesNotRecognizeSelector:sel]; // 若仍然无法响应,则报错:找不到响应方法
}
}
@end
网友评论