美文网首页
2019-01-11

2019-01-11

作者: 乂滥好人 | 来源:发表于2019-01-11 11:37 被阅读7次

方法列表(objc_method_list)结构

先了解方法结构

struct objc_method {
    // 方法名称   
    SEL _Nonnull method_name                                 OBJC2_UNAVAILABLE;
    // 方法类型(编码格式 (类型c语言的字符串) (函数的类型:返回值类型 参数类型)
    //  ”v@:”意思就是这已是一个void类型的方法,没有参数传入。
    // “i@:”就是说这是一个int类型的方法,没有参数传入。
    // ”v@:@”意思就是这已是一个void类型的方法,有参数传入。
    //  */class_addMethod([self class], sel,@selector(testMethod),"v@:");
    char * _Nullable method_types                            OBJC2_UNAVAILABLE;
    // 法的实现 ———— 函数的入口(函数的指针 函数名 是啥都可以 不一定和sel相同)
    IMP _Nonnull method_imp                                  OBJC2_UNAVAILABLE;
}  

方法列表结构

struct objc_method_list {
    // 函数列表
    struct objc_method_list * _Nullable obsolete             OBJC2_UNAVAILABLE;
    // 函数中的个数
    int method_count                                         OBJC2_UNAVAILABLE;
#ifdef __LP64__
    int space                                                OBJC2_UNAVAILABLE;
#endif
    // 函数列表中的第一个函数地址
    struct objc_method method_list[1]                        OBJC2_UNAVAILABLE;
}  

分类是如何实现的?

category结构

typedef struct category_t  {
    // 类的名字
    constchar *name;
    // 类
    classref_tcls;
    // 所有给类添加的实例方法的列表
    structmethod_list_t *instanceMethods;
    // 所有添加的类方法的列表
    structmethod_list_t *classMethods;
    // 实现的所有协议的列表
    structprotocol_list_t *protocols;
    // 添加的所有属性}category_t;
    structproperty_list_t *instanceProperties;
};

创建的分类(category)实际上是自定义的一个方法列表,这个分类列表被参入到类(class)的方法列表(objc_method_list)的结构中,如此一来,在外部调用的时候就能在方法列表中找到分类方法。
注:分类(category)中的实例方法、协议及属性 是添加到类上,而分类(category)的类方法和协议方法是添加到类的主类(meta class)上的。

分类为什么会"覆盖"掉原来的方法?

实际上如果分类(Category)和原来类都有相同的方法(testMethod),那么Category附加完成之后,类的方法列表里会有两个该方法(testMethod),而不是直接替换的。
Category的方法被放到了新方法列表的前面,而原来类的方法被放到了新方法列表的后面,这也就是我们平常所说的Category的方法会“覆盖”掉原来类的同名方法,这是因为RunTime在查找方法的时候是顺着方法列表的顺序查找的,它只要一找到对应名字的方法,就会停止。

相关文章

网友评论

      本文标题:2019-01-11

      本文链接:https://www.haomeiwen.com/subject/wiwtdqtx.html