oc 调用方法就是给对象发消息
msgSend:
给分类添加的方法,在app运行时,都会加载到类的类对象或者元类对象中.
在\通过runtime动态的将分类的方法合并的类对象,元类对象中的
类的结构如下
分类中的方法会加载到class_rw_t 里面 的methods 中, methods 是一个二维数组,每个数组存在的方法是1个分类的所有方法,最后编译的分类的方法数组在二维数组的最前面. 属性和协议也都是同样的操作
分类的底层结构
在编译后 分类全部转变为这种结构的结构体,即每一个分类都会转化成这种类型的结构体.
方法全部放在instance_methods ,class_methods 数组中去
协议放在protocols中
属性放在properties 中
cls 就是本类的地址
name 就是本类的名称
通过RunTime 加载某个类的所有Category数据.即取方法列表,协议等
即先编译的会在数组前面, 运行时通过倒叙遍历分类的列表,并取出方法列表放在二维方法列表的前面,- 最终效果为后编译的分类方法列表会在运行时加载到二维方法列表的前面,最终形成一个方法列表method_list_t *mlist的数组,再把mlist 处理到class_rw_t中方法列表,处理过程为
1.先根据mlist 的高度即长度,扩容class_rw_t 的方法列表,先把原来中的数组移动的最后面,把显得数组放在最前面.
memmove 12 移动到23 是先移动2到3,在移动1到2.
先从大地址挪到
memcopy 若索引重复 即 12的内存 移动到 23 中,先移动1的内存到2中,再把2的内存移动到3中,会把原来内存中的2覆盖掉, 即从小地址一个一个的往后挪.
类的扩展是在编译的时候就把定义的属性放在了.h中,并把这些属性处理成私有的权限.