1. 来看一段OC代码
QKTeacher *teacher = [[QKTeacher alloc] init];
[super setName:@"刘邦"];
[teacher greet];
编译后的代码
QKTeacher *teacher = objc_msgSend(objc_getClass("QKTeacher"), @selector(alloc));
teacher = objc_msgSend(teacher, @selector(init));
struct objc_super teachSuper = {teacher,class_getSuperclass(objc_getClass("QKTeacher"))};
objc_msgSendSuper(&teachSuper, @selector(setName:),@"刘邦");
objc_msgSend(teacher, @selector(greet));
动态添加方法
+ (BOOL)resolveClassMethod:(SEL)sel {
if ([NSStringFromSelector(sel) isEqualToString:@"newMethord:"]) {
class_addMethod(self, sel, (IMP)newMethord, "v@:@");
}
return [super resolveClassMethod:sel];
}
void newMethord(id self, SEL _cmd,NSString *str) {
NSLog(@"str : %@",str);
}
// 消息调用
objc_msgSend(tearcher, @selector(newMethord:),@"刘邦");
小结
- 对于[QKTeacher alloc]这样的消息,编译时会转化成objc_msgSend()函数
- objc_msgSend() 包括消息的发送者,消息的名字,参数。
- objc_msgSend() 有两个隐含的参数 id self 和 SEL _comd
- [super setName:@"刘邦"] 这样的消息,编译时会转化成 objc_msgSendSuper
- objc_msgSendSuper() 包括父类的结构体指针、方法、方法的参数
- struct objc_super 这个结构体里边包括子类的实例,子类的父类的名称
2. OC 消息的运行流程
1.转换成objc_msgSend
objc_msgSend
2.查找方法的实现
查找IMP
3.消息转发
1.1 类方法转发前处理 + (BOOL)resolveClassMethod:(SEL)sel;
1.2 实例方法转发前处理+ (BOOL)resolveInstanceMethod:(SEL)sel
2.重定向消息 - (id)forwardingTargetForSelector:(SEL)aSelector
3.消息转发 - (void)forwardInvocation:(NSInvocation *)anInvocation
4.如果都没处理,就会报找不到消息的异常
网友评论