OC基础Category和Extension区别

Category 和 Extension介绍

Category
  • 可以给当前已知的类添加方法(类方法和实例方法),这个类可以是自定义的类,也可以是系统自带的类。当添加的方法和类的原有方法重名时,会‘覆盖’类的原有方法.

原类的方法还是存在的,并不是真的给覆盖了。因为在运行时当给对象发消息,会根据对象的‘isa’指针找到所属的类,然后在类的方法列表中根据方法名寻找,当找到第一个就返回了,而通过category添加的方法又在方法列表的最上面所以没有机会找到类原来方法`。

  • 可以通过property添加属性,但也只是对属性的set、get方法声明,没有实现,也不能生成带下划线的变量。
  • 不能添加成员变量。注意,通过runtime 关联对象添加的不叫属性,也不叫成员变量,它和当前类没有根本上的关系,只是仅仅的连在了一起。
Extension
  • 可以给一个已知的类添加方法(类方法和实例方法),这个类只能是自定义的类,不可以是系统自带的类,因为不能得到.m文件。由于在已知的类.m 中操作所以可以对外界隐藏一些方法或变量,使其成为私有。
  • 可以添加属性和成员变量,也可以为属性生成set、get方法和默认的实现。通过extension添加的方法和变量真的成为了当前类的一部分。

不同之处

eg:分别给自定义的User类添加Category,Extension

//Category
@interface User (InnterAdd)
-(void)test;
@end
@implementation User (InnterAdd)

-(void)test
{
    NSLog(@":%s",__func__);
}

@end

//Extension
@interface User ()

@property (copy)NSString * addr;

@end

表现形式上,Category有名称,有自己的.m文件,extension没有名称看起来像个匿名的分类,没有.m文件。 Category也可以没有名称,这样两者在表现上就一样了。

Category: 是在运行时加载处理的,这个过程中把添加的方法添加到类的方法列表中,由于类的内存结构布局是在编译时期确定的,所以在运行时不能再添加实例变量否则就破坏了内存结构(访问非法内存地址存在不可预知的错误,所以是禁止的)。那为啥能添加方法而不能添加成员变量呢?在runtime层,category用结构体category_t(在objc-runtime-new.h中可以找到此定义)如下:

typedef 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;
} category_t;

从中可看出可以添加实例方法,类方法,甚至可以实现协议,添加属性。没有表示实例变量的存贮。

其实分类本身而言它就不是一个类,分类,分开类的一部分操作,就是一个在运行时给主类添加方法、属性、或者协议的操作或者对外提供的一种接口扩展,在分类中添加方法直接绑定到主类原有的方法列表。所以感觉把分类这个名字改为方法扩展更容易理解(o)/~,所以在这一点来看,Category和Extension在目的上还是一致的,都是对原有的类增加新的操作。

Extension:在编译时处理的,添加的变量和方法和类密切的在一起,就是类的一部分,类消失它也消失。

Category中关联对象

runtime提供了以下三个方法

void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
objc_getAssociatedObject(id object, const void *key)
void objc_removeAssociatedObjects(id object)

其中objc_removeAssociatedObjects 移除已添加的所有对象,所以实际操作要注意别把其他地方添加的关联也给remove了。所以还是通过objc_setAssociatedObject 直接置为nil更为可靠。

#END

上一个问题:OC面试基础(1)— 说下@property关键字及修饰符

你可能感兴趣的:(OC基础Category和Extension区别)