Runtime - isa 类的具体结构

1.runtime的作用

OC是一个动态性较强的语言,其动态的本身就是因为runtime,把编译过程中的某些东西放到运行时来做

所以runtime的作用:

1.动态的创建类,比如KVO的新类就是运行的时候创建的

2.访问已有类的各种属性/方法,比如JSON转Model

3.修改或者添加成员属性和方法

4.消息机制,消息转发  实际应用少,但面试贼多,可以处理找不到函数产生的闪退

2.runtime的底层架构

runtime的本质就是操作isa superClass这些指针去访问

isa取值的问题

isa从64位系统开始,引入了位域和共用体的

比如0x 01101010 取出它的第二位

用.  0x 00000010去&上它就好了

    int a = 0b00001101;
    int b = 0b00000010;
    int c = 0b00000100;
    printf("%d",a & b);  //0 取出第二位,因为第二位是0所以结果是0b000,也就是0
    printf("%d",a & c);  //4 转换成二进制就是0b100,也是取出了第三位

比如上面代码,用b取出了第二位,用c取出了第三位

 再改下:

 int a = 0b00001101;
 int b = 2;
 int c = 4;
 printf("%d",a & b);  //0 取出第二位,因为第二位是0所以结果是0b000,也就是0
 printf("%d",a & c);  //4 转换成二进制就是0b100,也是取出了第三位

也是一样的结果,因为0b00000100就是10进制的4,0b00000100就是十进制的2

再补充下位移:

int a = 0b00001101;
int b = 1 << 1;    //把1向左移动移移动一位就是0b000010 也就是十进制的2
int c = 1 << 2;    //把1向左移动两位就是0b000100 也即使十进制的4
printf("%d",a & b);  //0 取出第二位,因为第二位是0所以结果是0b000,也就是0
printf("%d",a & c);  //4 转换成二进制就是0b100,也是取出了第三位

上述这种叫位操作,只操作某一位,比如说,某一位只存储bool值,所有位都有一个单独的bool属性,这个就叫位域,目的就是一个值,&上不同的值,来得到多种不同的值,以达到节约空间的目的,Union(共用体)就是这个目的,isa就用了位域和共用体如下 

 简单了解就好

class的内存结构

不管怎么样,isa还是拿到了类对象的存储地址,

类的内存结构:

 大概如上,值得一提的是 ro里面的内容是不能修改的,就是右边的那一块

method_list_t(方法列表)

 

 两种的最终结果都是method_t

 也不解释了,注释很清楚,第一个是函数名称,项目常用,我们可以用到的是字符串,C语言输出字符串的方式输出

NSLog(@"%s",@selector(test))

方法缓存列表

cache_t是方法的缓存列表,用散列表存储用过的方法,提高方法的查找速度

 所以可以看出这个散列表是个数组,但又有键值对,所以更像是字典

所以散列表肯定也不是遍历整个数组,而是存储地址具有某种规律,用,@selector(test)对应的SEL去&cache_t里面的mask能得到散列表对应的起始值,然后根据这个起始值再进行遍历,是+还是减,要根据架构来,源码区分了x86和x64架构,在objc源码->objc-cache->cache :: find这个函数里面,另外再提一句,苹果里面很多的查找方式都是用的&机制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值