类拓展

262 阅读2分钟

属性和方法的添加

类拓展是直接可以添加属性和方法的可以做到直接直接访问,但是分类中可以直接添加属性,却无法直接添加属性,如果添加属性,访问的话就会这样:

erminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[LGPerson setCate_name:]: unrecognized selector sent to instance 0x100f397a0'

没有实现set方法,这是什么原因呢?因为类拓展是编译时,直接将信息增加到ro,分类运行时不可以操作ro,所以添加属性的时候实现其set和get方法的关联

-(void)setCate_name:(NSString *)cate_name{
/**
参数一:id object : 给哪个对象添加属性,这里要给自己添加属性,用self。
参数二:void * == id key : 属性名,根据key获取关联对象的属性的值,在objc_getAssociatedObject中通过次key获得属性的值并返回。
参数三:id value : 关联的值,也就是set方法传入的值给属性去保存。
参数四:objc_AssociationPolicy policy : 策略,属性以什么形式保存。
*/
objc_setAssociatedObject(self, @"namee",cate_name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

-(NSString *)cate_name{
/**
参数一:id object : 获取哪个对象里面的关联的属性。
参数二:void * == id key : 什么属性,与objc_setAssociatedObject中的key相对应,即通过key值取出value。
*/
return objc_getAssociatedObject(self, @"namee");
}

+(void)load加载

load的实现是决定类是在编译器加载还是在运行期加载,那么分类和主类中都实现了+(void)load方法那么分类会覆盖主类吗?我们来做验证:

2020-04-07 16:31:01.704915+0800 objc-debug[11310:250082] 主类+[LGPerson load]

2020-04-07 16:31:01.706193+0800 objc-debug[11310:250082] 分类+[LGPerson(LG) load]

根据打印信息我们了解到分类的load方法并不会覆盖主类,都会执行,执行顺序是先分类后主类 

load_images分析

改方法是底层load方法调用顺序

主类:add_classs_to_loadable_list->loadable_classes->call_class_loads->load

分类:add_category_to_loadable_list->loadable_categories->call_category_loads->load


+(void)initialize

该方法的调用实在运行时,类被调用的时候进行实现,子类被调用时候,会先判断父类有没有被调用,如果没有的话会首先调用父类initialize然后调用自己的initialize。

如果分类中实现了initialize方法,那么主类中的initialize方法将不会被再调用