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, ... );

特殊情况:

  1. [obj performSelector:@select(method)] 和 [obj method] 意思一致,可是调用本质上不一样。
    特别是obj --> super
    说明:
    [super viewDidLoad] 调用的是superClass的方法, 数据是Self
    [super performSelector:@select(viewDidLoad)] 调用的是self的方法 (respondsToSelector 也是同效果)

    所以不要用:
    super, respondsToSelector和performSelector 组合, 会形成死循环

  1. 可能调用的是 super performSelector ; performSelector 中的方法中调用的是 subClass类的实现
  2. 用 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

参考
https://blog.csdn.net/likendsl/article/details/44085569

你可能感兴趣的:(OC - Runtime 一点思考)