OC - Runtime 一点思考
class_addMethod
1.Sel在 class 中有实现了就不能成功; Sel在class中没有Imp就能添加成功(即使有定义)
2.class单指本类,和superclass无关 (即使superClass 实现了Sel,也可以添加成功)
method_getImplementation
获取的实时的Imp
super (self中的super调用还是本身,和super本质有关)
struct objc_super { id receiver; Class superClass; };
receiver --> 当前类 (self)
superClass ---> 这个类的父类
实际上只是一个”编译器标示符”,它负责告诉编译器,当调用viewDidLoad方法时,去调用父类的方法,而不是本类中的方法。
不是调用objc_msgSend函数,而是调用objc_msgSendSuper函数
id objc_msgSendSuper ( struct objc_super *super, SEL op, ... );
特殊情况:
-
[obj performSelector:@select(method)] 和 [obj method] 意思一致,可是调用本质上不一样。
特别是obj --> super
说明:
[super viewDidLoad] 调用的是superClass的方法, 数据是Self
[super performSelector:@select(viewDidLoad)] 调用的是self的方法 (respondsToSelector 也是同效果)所以不要用:
super, respondsToSelector和performSelector 组合, 会形成死循环
- 可能调用的是 super performSelector ; performSelector 中的方法中调用的是 subClass类的实现
- 用 self去调用 super的Sel的Imp (self 提供的数据)
[super respondsToSelector:@selsector(methodOnlyInSub)]
objc_msgSendSuper(objc_super *super, @selector(respondsToSelector:) ) --> 判断出super有
--> 可能 objc_msgSend(objc_super.receiver, @selector(respondsToSelector:)) = objc_msgSend(self,@selector(respondsToSelector:)) --> 在 respondsToSelector 方法里,就成了
objc_msgSend(self, @(methodOnlyInSub)) 在self 类方法中找实现
调用 objc_msgSendSuper 的方法,将这个结构体和 respondsToSelector 的 sel 传递过去。函数里面在做的事情类似这样:从 objc_super 结构体指向的 superClass 的方法列表开始找 respondsToSelector 的 selector,找到后再以 objc_super->receiver 去调用这个 selector,可能也会使用 objc_msgSend 这个函数,不过此时的第一个参数 theReceiver 就是 objc_super->receiver,第二个参数是从 objc_super->superClass 中找到的 selector