category结构体
typedef struct category_t {
const char *name; // 类名
classref_t cls; // 类
struct method_list *instanceMethods; // 实例方法列表
struct method_list *classMethods; // 类方法列表
struct protocol_list_t *protocols; // protocol
struct property_list_t *instanceProperties; // 添加的所有属性
} category_t;
从category的定义可以看出category可以添加实例方法,类方法,实现协议,添加属性,不可添加实例变量
category
为已经存在的类添加方法
在运行期决定,无法添加实例变量,因为在运行期,对象的内存布局已经确定,如果添加实例变量就会破坏类的内部布局。
category的方法没有完全替换原来类已经有的方法,也就是说如果category和原来的类都有methodA,那么category附加完之后,类的方法列表里会有两个methodA
category的方法被放到了新方法列表的前面,runtime在查找方法的时候是顺序查找,这样会先找到category的方法,然后直接返回。
如果两个category里都有methodA,要看compile sources 里的文件加载顺序,哪个在后执行哪个的methodA
extension
在编译期决定,它就是类的一部分,在编译期和头文件里的@interface以及实现文件的@implement一起形成一个完成的类,它伴随类的产生而产生,亦随之一起销亡。
extension一般用来隐藏类的私有信息,你必须有一个类的源码才能为一个类添加extension.所以你无法为系统的类比如NSString添加extension.
网友评论