分类(Category
)是OC中的特有语法,它是表示一个指向分类的结构体的指针。原则上它只能增长方法,不能增长成员(实例)变量。markdown
为已经存在的类添加方法。能够在不修改原来类的基础上,为一个类 扩展方法。最主要的应用:给系统自带的类 扩展方法。this
1.分类中只能添加“方法”,不能增长成员变量。分类中的能够写@property
, 但不会生成setter/getter
方法, 也不会生成实现以及私有的成员变量,会编译经过,可是引用变量会报错。spa
2.分类中能够/只能
访问原有类中.h中的属性。若是想要访问本类中的私有变量,分类和子类同样,只能经过方法来访问。ssr
3.在本类和分类有同名方法时,优先调用分类的方法
。同名方法调用的优先级为分类 > 本类 > 父类
。3d
4.若是多个分类中都有和原有类中同名的方法,那么调用该方法的时候执行谁由编译器决定;编译器会执行最后一个参与编译
的分类中的方法。指针
分类方法不会覆盖掉原来类中的方法,而是共存的。可是分类中的方法在前面,原来的类中的方法在后面,调用的时候,就会调用分类中的方法,若是多个分类有一样的方法,后编译的分类会调用。code
例如,建立一个UIView的分类:orm
在新建的文件的.h中声明新方法,在.m中具体实现方法 格式:对象
@interface 待扩展类的类名(分类名字)
/*方法声明*/
@end
@implementation 待扩展类的类名(分类名字)
/*方法实现*/
@end
复制代码
编译完以后每个分类都会生成一个结构体category_t
,里面存储着分类的对象方法、类方法、属性、协议信息。在程序运行的时候,runtime会将Category的数据,合并到类信息中(类对象、元类对象中)继承
struct category_t {
const char *name;
classref_t cls;
struct method_list_t *instanceMethods;
struct method_list_t *classMethods;
struct protocol_list_t *protocols;
struct property_list_t *instanceProperties;
// Fields below this point are not always present on disk.
struct property_list_t *_classProperties;
method_list_t *methodsForMeta(bool isMeta) {
if (isMeta) return classMethods;
else return instanceMethods;
}
property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
};
复制代码
.h中
#import <UIKit/UIKit.h>
@interface UIImage (Size)
- (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize ;
@end
复制代码
.m中
#import "UIImage+Size.h"
@implementation UIImage (Size)
- (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
@end
复制代码
1.类扩展(extension
)是Category
的一个特例,有时候也被称为匿名分类。他的做用是为一个类添加一些私有的成员变量和方法。 2.和分类不一样,类扩展便可以声明成员变量又能够声明方法。 3.分类的小括号中必须有名字
Class Extension
在编译的时候,它的数据就已经包含在类信息中。 Category
是在运行时,才会将数据合并到类信息中。
有load方法,load方法在runtime加载类、分类的时候调用。load方法能够继承,可是通常状况下不会主动去调用load方法,都是让系统自动调用。