1.category
方法的调用顺序:category>本类>父类
为什么category不能直接添加属性:
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE; // 父类
const char *name OBJC2_UNAVAILABLE; // 类名
long version OBJC2_UNAVAILABLE; // 类的版本信息,默认为0
long info OBJC2_UNAVAILABLE; // 类信息,供运行期使用的一些位标识
long instance_size OBJC2_UNAVAILABLE; // 该类的实例变量大小
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; // 该类的成员变量链表
struct objc_method_list **methodLists OBJC2_UNAVAILABLE; // 方法定义的链表
struct objc_cache *cache OBJC2_UNAVAILABLE; // 方法缓存
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; // 协议链表
#endif
} OBJC2_UNAVAILABLE;
这是类的结构体
ivars指向的是一个固定区域,只能修改成员变量值,不能增加成员变量个数;methodList是一个二维数组,所以可以修改*methodLists的值来增加成员方法;
category中能添加属性吗:
Category实际上允许添加属性的,同样可以使用@property,但是不会生成_变量(带下划线的成员变量),也不会生成添加属性的getter和setter方法的实现
生成方法?
需要注意的有两点:
1)、category的方法没有“完全替换掉”原来类已经有的方法,也就是说如果category和原来类都有methodA,那么category附加完成之后,类的方法列表里会有两个methodA。
2)、category的方法被放到了新方法列表的前面,而原来类的方法被放到了新方法列表的后面,这也就是我们平常所说的category的方法会“覆盖”掉原来类的同名方法,这是因为运行时在查找方法的时候是顺着方法列表的顺序查找的,它只要一找到对应名字的方法,就会罢休,殊不知后面可能还有一样名字的方法。
category添加属性:
static NSString *nameSetterGetterKey =@"nameWithSetterGetterKey";
- (void)setNameWithSetterGetter:(NSString *)nameWithSetterGetter {
objc_setAssociatedObject(self, &nameSetterGetterKey, nameWithSetterGetter, OBJC_ASSOCIATION_COPY);
}
- (NSString *)nameWithSetterGetter {
returnobjc_getAssociatedObject(self, &nameSetterGetterKey);
}
2.extension:
上图是extension的使用,并没有多大用处,只是可用用来声明一个外部无法访问的全局属性