1.Category底层结构,如下

ios方法调用 ios调用方法原理_类方法

2.使用指令从编译后的c++代码,也可以看出是把在分类中写的方法都赋值给了结构体

将Objective-C代码转换为C\C++代码

xcrun -sdk iphoneos clang  -arch  arm64 -rewrite-objc  OC源文件  -o  输出的CPP文件

如果需要链接其他框架,使用-framework参数。比如-framework UIKit

ios方法调用 ios调用方法原理_子类_02

ios方法调用 ios调用方法原理_消息机制_03

第一张图中圈的值赋值给了第二张的结构体属性里。

3.分析Category怎么把方法合并到类中的。

是通过dyld装载程序,初始化runtime环境的时候加载到类对象里

ios方法调用 ios调用方法原理_消息机制_04

直到最后调用到如下方法

ios方法调用 ios调用方法原理_子类_05

上图中圈中2行代码做的事情就是把分类的方法列表加到原始类的方法列表前面。

所以最终会导致,对象调用方法时,先找到分类的方法进行调用。

也就是我们常说的分类方法会“覆盖”原来类的方法的现象,但实际上并不是覆盖,而是因为分类方法被添加在了前面。

因为消息机制isa在查找方法的时候找到就直接调用了,后面不会再管了。

 

4.我们所写的就分类的方法,如果重名的话,会由编译顺序决定调用哪一个。

还有一点要注意就是写静态库里other linker flags 设置成 -all_load。

5.+load方法的调用

也是在dyld装载程序,初始化runtime环境的时候调用的。所以代码不管是否使用就会调用。

ios方法调用 ios调用方法原理_消息机制_06

最后调用

ios方法调用 ios调用方法原理_子类_07

ios方法调用 ios调用方法原理_类方法_08

而且两个方法内部调用都是直接方法调用,没有使用objc消息机制。

所以写了原类,子类,分类.三个类里面的+load都会依次调用。

6.+initialize方法, 首次使用类的时候只会调用一次

ios方法调用 ios调用方法原理_子类_09

可以看到方法调用采取的是objc消息机制调用,

所以结果为

比如写了原类,子类,分类.三个类里面的+initialize方法,只有原类、分类依次调用。

5和6的调用结果如下图

ios方法调用 ios调用方法原理_ios方法调用_10

PS:介于时间有限,本篇只列了一些重点并不算是详细,