Category中分类覆盖原类中的方法

现象:

1、分类中的方法是会覆盖原类中的方法的
2、多个分类中的同样的方法,会按照编译的顺序,执行最后编译的分类中的方法

原理

Category对应的结构体我们可以通过将分类的.m文件转成c++文件查看:
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc LZPerson+text.m
即可生成对应的.cpp文件;
在.cpp文件中搜索Category_t可以看到Category对应的结构体:

struct _category_t {
const char *name;
struct _class_t *cls;
const struct _method_list_t *instance_methods;
const struct _method_list_t *class_methods;
const struct _protocol_list_t *protocols;
const struct _prop_list_t *properties;
};

通过观察结构体我们可以发现分类对应的结构体中有存储实例方法的列表、存储类方法的列表、存储协议的和属性的列表。

所以

  • 分类一般用来动态的为已经存在的类扩展新的方法。
  • 分类中可以添加实例方法、类方法、属性、协议。但是不能添加成员变量。
  • 添加属性的话只会生成set、get方法的声明不会实现也不会生成下划线成员变量。

分类覆盖原因

系统是在运行时将分类中对应的实例方法、类方法等插入到了原来类或元类的方法列表中,且是在列表的前边!所以,方法调用时通过isa去对应的类或元类的列表中查找对应的方法时先查到的是分类中的方法!查到后就直接调用不在继续查找。这即是’覆盖’的本质!

存在多个分类,调用谁?

这个是与编译顺序有关,最后编译的分类中对应的信息会在整合在类或元类对应列表的最前边。所以是调用最后编译的分类中的方法!可以查看Build Phases ->Complie Source 中的编译顺序!

参考资料:
https://www.jianshu.com/p/dd57c39a5e4c
https://tech.meituan.com/2015/03/03/diveintocategory.html

你可能感兴趣的:(Category中分类覆盖原类中的方法)