1. 预备知识
在看源码之前我们先看一下objc中对于ivar,method,property的源码,由于网上现在很多关于runtime还在用objc2.0之前的源码,本来也打算这么做,但是本着匠心精神,做事要严谨,还是把新的代码给翻出来了
1.1 ivar
1 2 3 4 5 6 7 8 |
struct ivar_t { int32_t *offset; const char *name; const char *type; uint32_t alignment_raw; uint32_t size; uint32_t alignment() { if (alignment_raw == ~(uint32_t)0) return 1U |
ivar关键的属性有3个跟今天要讲的有关系的属性是name,type,offset,分别对应ivar的名字,类型和偏移量,偏移量这个说来话长,想仔细深入的推荐看《程序员的自我修养》,你会在里面的到一个满意的解答
1.2 property
1 2 3 4 |
struct property_t { const char *name; const char *attributes; }; |
每一个property中都有一个name代表着属性名,attributes就是上一节我们说到的关于一个属性的声明描述,如属性的原子性、内存管理规则等描述都存放在这里
1.3 Method
关于method要说的东西比较多,我们先看一下method的源码
1 2 3 4 5 6 7 8 9 |
struct method_t { SEL name; const char *types; IMP imp; struct SortBySELAddress : public std::binary_function { bool operator() (const method_t |
在这里我们需要了解SEL和IMP分别是什么:
在执行的时候,runtime会为每一个class准备一张virtual table表,表格里以字符串当key,每个key会对应到C function的指针位置。在runtime里,将C function 定义为IMP,将key的C字符串定义为SEL,叫做selector type:
![](http://file.zhishichong.com/images/article/20161028/4743edac752f2785f6ba7dfa3e8637bd.png)
SEL: 方法ID
1 |
typedef struct objc_selector *SEL; |
1 2 3 4 |
struct objc_selector { char *name;// 名称 char *types;// 类型 }; |
IMP:函数指针 C function Point
1 |
typedef id (*IMP)(id, SEL, ...); |
了解了SEL和IMP之后我们再来看method的定义,不难看出method中有方法名的字符串和方法的访问地址,顺便存储了方法的类型,当然还要有返回类型和参数类型,这样就构成了一个method。
既然预备工作已经做好了,我们就来看YYModel的对这三项的封装
2. YYClassIvarInfo
1 2 3 4 5 6 |
/** Instance variable information. 增加了对IVar的描述 */ @interface YYClassIvarInfo : NSObject @property (nonatomic, assign, readonly) Ivar ivar; /// |
这里为什么要对这个ivar的内存偏移地址和类型等这些,这里这样做是为了后面处理起来的时候,可以直接在外面暴露的地方获取到这些属性,而不需要再用runtime获取对应的内容,也可以增加内存的命中率。(目前来说读源码到这里的理解是这样,后面读着如果有其他理解我会进行修改)
1
ivar关键的属性有3个跟今天要讲的有关系的属性是name,type,offset,分别对应ivar的名字,类型和偏移量,偏移量这个说来话长,想仔细深入的推荐看《程序员的自我修养》,你会在里面的到一个满意的解答 1.2 property
每一个property中都有一个name代表着属性名,attributes就是上一节我们说到的关于一个属性的声明描述,如属性的原子性、内存管理规则等描述都存放在这里 1.3 Method关于method要说的东西比较多,我们先看一下method的源码
在这里我们需要了解SEL和IMP分别是什么: ![]() SEL与IMP
SEL: 方法ID
IMP:函数指针 C function Point
了解了SEL和IMP之后我们再来看method的定义,不难看出method中有方法名的字符串和方法的访问地址,顺便存储了方法的类型,当然还要有返回类型和参数类型,这样就构成了一个method。 2. YYClassIvarInfo
这里为什么要对这个ivar的内存偏移地址和类型等这些,这里这样做是为了后面处理起来的时候,可以直接在外面暴露的地方获取到这些属性,而不需要再用runtime获取对应的内容,也可以增加内存的命中率。(目前来说读源码到这里的理解是这样,后面读着如果有其他理解我会进行修改) |