美文网首页
OC - Runtime 一点思考

OC - Runtime 一点思考

作者: chenhh6701 | 来源:发表于2019-03-21 14:13 被阅读0次

    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 一点思考

          本文链接:https://www.haomeiwen.com/subject/uubqvqtx.html