iOS 分类和扩展
分类 Category
分类(Category)是OC中的特有语法,它是表示一个指向分类的结构体的指针。原则上它只能增加方法,不能增加成员(实例)变量。
分类 Category 属性和成员变量
在分类中可以写@property, 但是不会生成setter/getter方法,也不会实现成员变量。如果强制使用会报错。
不过可以通过runtime的关联对象的方法在Category使用成员变量
新建PersonModel文件
// PersonModel.h@interfacePersonModel:NSObject@property(assign,nonatomic)intage;@end// PersonModel.m#import"PersonModel.h"@implementationPersonModel@end
为PersonModel创建Category
// PersonModel+Category.h@interfacePersonModel(Category)@property(copy,nonatomic)NSString*name;@property(copy,nonatomic)NSString*objName;@end// PersonModel+Category.m#import"PersonModel+Category.h"#importstaticNSString*objNameKey=@"objNameKey";@implementationPersonModel(Category)-(void)setObjName:(NSString*)objName{objc_setAssociatedObject(self,&objNameKey,objName,OBJC_ASSOCIATION_COPY_NONATOMIC);}-(NSString*)objName{returnobjc_getAssociatedObject(self,&objNameKey);}@end
使用
PersonModel*person=[PersonModel new];person.age=10;NSLog(@"person age = %d",person.age);// 复值失败,因为Category只是添加了属性,没有添加成员变量// person.name = @"jack";// NSLog(@"person name = %@",person.name);person.objName=@"jack";NSLog(@"person objName = %@",person.objName);
返回
person age = 10person objName = jack
分类 Category 同名方法执行顺序
同名方法执行顺序为 分类 > 本类 > 父类
如果多个分类和本类有同名的方法,调用该方法的时候执行由编译器决定。
在RootController
-(void)viewWillAppear:(BOOL)animated{[superviewWillAppear:animated];NSLog(@"name = %@",self);}
为RootController创建Category
-(void)viewWillAppear:(BOOL)animated{[superviewWillAppear:animated];NSLog(@"Category name = %@",self);}
返回
Category name=<RootController:0x12df0ec90>
扩展
Extension:扩展, 延展, 匿名分类;放在.m文件中。一般用于声明私有属性(不对子类暴露)、声明私有方法、声明私有成员变量。
创建PersonModel的Extension - PersonModel+Ex
@interfacePersonModel()@property(copy,nonatomic)NSString*exStr;-(void)exDemo;@end
在PersonModel.m里处理exStr和exDemo
-(void)exDemo{PersonModel*model=[PersonModelnew];model.exStr=@"Ex";NSLog(@"ex = %@",model.exStr);}
分类和扩展的区别
分类(Category)扩展(Extension)
运行时决议编译时决议
有单独的.h和.m文件以声明的方式存在,寄生于宿主类的.m文件
可以为系统类添加分类不能为系统类添加扩展
看不到源码的类可以添加分类没有.m源码的类无法为其添加扩展
网友评论