-
分类即Category
- 分类可以添加方法,也可以写添加属性,但是因为没有生成对应的成员变量和setter、getter方法,因此没有实际属性意义;
- 分类里面不允许使用关键字@synthesize;
- 将不同的功能分摊到不同的文件,减轻单个文件的体积;
- 多人共同开发同一个类的不同分类,按需加载不同的分类;
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
};
从上面可以看出分类可以添加实例方法、类方法、协议、属性,但是不能添加实例变量。
-
扩展即Extension
- 为某个类附加额外的属性、成员变量以及方法声明,因为一般是依附于.m文件里面,所以一般都是私有变量,当然也可以单独作为一个文件存在.h文件里面;
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;
-
extension是在编译器决定的,而category是在运行期决定的。
在runtime 中,objc_class 结构体大小是固定的,不可能往这里添加数据,只能修改。所以,ivars 指向了一个固定区域,只能修改成员变量的值,不能增加成员变量的个数。方法列表是一个二维数组,可以修改 *methodLists的值来增加成员方法,虽然没办法扩展methodLists指向的内存区域,却可以改变这个内存区域的值(里面存的是指针),因此,可以动态添加方法,不可以添加成员变量。
网友评论