swift与oc方法查找比较

2021-10-01  本文已影响0人  不拘小节123456

对于oc的方法查找大家比较熟悉了,所有的方法调用都会走objc_msgSend
该api必须两个参数,receiver和SEL,receiver就是该对象的isa指针,然后先在cache里面查找,如果没找到再去methodLists里面查找,如果还没有就去superclass里面找进行递归操作,都找不到就会进行消息转发操作
下面是老版的runtime,但是逻辑类似,好理解

struct objc_class : objc_object {
    Class superclass;
    const char *name;
    uint32_t version;
    uint32_t info;
    uint32_t instance_size;
    struct old_ivar_list *ivars;
    struct old_method_list **methodLists;
    Cache cache;
    struct old_protocol_list *protocols;
    // CLS_EXT only
    const uint8_t *ivar_layout;
}
//  方法的定义
typedef struct objc_method *Method;
struct objc_method {
    SEL method_name                                          OBJC2_UNAVAILABLE;
    char *method_types                                       OBJC2_UNAVAILABLE;
    IMP method_imp                                           OBJC2_UNAVAILABLE;
}

对于swift,它分为三种派发方式:静态派发,动态派发和消息派发(就是oc里面的派发方式)
静态派发是最快的.我理解就是在编译的时候已经确定了函数地址进行直接调用,具体api如:static 修饰func,extension包含的func
动态派发:他引入了v-table表的概念,从swift源码看v-table表在编译的时候回存储在metal对象里面,调用查找方式类似消息发送查找,不同的是他的查找相对淳朴,直接采用指针偏移点方式查找,由于编译时已经确定v-table表,不需要消息发送那么复杂的缓存查找方式

可以通过SIL命令来查看当前类的v-table表
swiftc -emit-sil main.swift

void *
swift::swift_lookUpClassMethod(const ClassMetadata *metadata,
                               const MethodDescriptor *method,
                               const ClassDescriptor *description) {
  assert(metadata->isTypeMetadata());

  assert(isAncestorOf(metadata, description));

  auto *vtable = description->getVTableDescriptor();
  assert(vtable != nullptr);

  auto methods = description->getMethodDescriptors();
  unsigned index = method - methods.data();
  assert(index < methods.size());
// 根据方法描述取得该方法在vtable中的地址偏移
  auto vtableOffset = vtable->getVTableOffset(description) + index;
// 本身类的起始地址
  auto *words = reinterpret_cast<void * const *>(metadata);
// 得到动态方法的当前实际地址
  return *(words + vtableOffset);
}

参考
https://www.jianshu.com/p/985bef8dfd30
https://www.jianshu.com/p/ea01fe230b03
https://www.jianshu.com/p/a4ca25caa6c9

上一篇下一篇

猜你喜欢

热点阅读