OC 消息

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:),@"刘邦");

小结

  1. 对于[QKTeacher alloc]这样的消息,编译时会转化成objc_msgSend()函数
  2. objc_msgSend() 包括消息的发送者,消息的名字,参数。
  3. objc_msgSend() 有两个隐含的参数 id self 和 SEL _comd
  4. [super setName:@"刘邦"] 这样的消息,编译时会转化成 objc_msgSendSuper
  5. objc_msgSendSuper() 包括父类的结构体指针、方法、方法的参数
  6. struct objc_super 这个结构体里边包括子类的实例,子类的父类的名称

2. OC 消息的运行流程

1.转换成objc_msgSend


OC 消息_第1张图片
objc_msgSend

2.查找方法的实现


OC 消息_第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.如果都没处理,就会报找不到消息的异常

你可能感兴趣的:(OC 消息)