iOS Class的结构

一、底层结构

  • 我们可以通过runtime的底层源码看的class的底层结构体,简化如下:
    // Class ISA;
    isa_t isa; //isa指针
    Class superclass;
    cache_t cache;    //方法缓存cache       
    class_data_bits_t bits; 
}
  • 然后点进去之后他们之间的联系如图:


    WeChat1634addb04b95eb06580de030bc966ce.png
  • 由上图中我们的数据结构可知:
  1. class_rw_t里面的 methods、 properties、protocols 是二维数组,是可读可写的,包含了类的初始内容、分类的内容
  2. class_ro_t里面的baseMethodList、baseProtocols、ivars、baseProperties是一维数组,是只读的,包含了类的初始内容

二、method_t 是对方法\函数的封装

  • 我们经过class_rw_t -> class_ro_t -> method_list_t最终可以找到method_t的结构体, 简化后如下:
struct method_t {
    SEL name; // 函数名
    const char *types; // 编码(返回值 返回类型)
    IMP imp; // 指向函数的指针(函数地址)
}
  1. IMP代表函数的具体实现


    图片.png
  2. SEL代表方法名\函数名,一般叫选择器,底层结构跟char*类似
  • 可以通过@selector()和sel_registerName()获得
  • 可以通过sel_getName()和NSStringFromSelector()转成字符串
  • 不同类中相同名字的方法,所对应的方法选择器是相同的
  1. types包含了函数返回值,参数编码的字符串


    图片.png

三、方法缓存:

  1. Class内部结构中有个方法缓存(cache_t),用散列表(哈希表 )来缓存曾经调用过的方法,这样可以提高方法的查找速度


    图片.png
  2. 缓存查找 = selector(方法名)为_key&_mask 获取到对应的_imp
  • objc-cache.mm
  • bucket_t * cache_t::find(cache_key_t k, id receiver)

四、方法查找:

  • 我们知道实例对象的isa指向类对象,指向类对象的isa类对象,类对象的isa指向元类对象如图:


    图片.png
  • 最后其实属性列表,协议列表都是类似的结构和方法查找;

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容