iOS-分类和扩展的区别和联系

分类 (Category)


什么是分类:

分类就是类的补充和扩展部分,补充和扩展的每个部分就是分类。
分类本质上就是类的一部分,分类给特定类添加能力。


分类的定义方式:

主类类名+分类类名

分类文件也分为.h和.m文件
.h文件中存放分类的声明部分
.m文件中存放分类的实现部分


分类的作用:

分类中可以对本类添加额外的方法,比如说:有一个Person的本类,现在分类可以对Person本类添加其余的方法,可以添加eat(),run()等等方法。这样,在不修改本类的情况下,本类多出了eat(),run()等等方法。


怎么创建分类:
Command+N-->Objective-C File-->File Type:Category

分类注意点:

分类中不能添加属性!
分类中不能添加属性!
分类中不能添加属性! —重要的话要说三遍

为什么分类中不能添加属性呢?
因为分类的结构体中根本没有属性列表这一项。

Category
Category 是表示一个指向分类的结构体的指针,其定义如下:
typedef struct objc_category *Category;
struct objc_category {
  char *category_name                          OBJC2_UNAVAILABLE; // 分类名
  char *class_name                             OBJC2_UNAVAILABLE; // 分类所属的类名
  struct objc_method_list *instance_methods    OBJC2_UNAVAILABLE; // 实例方法列表
  struct objc_method_list *class_methods       OBJC2_UNAVAILABLE; // 类方法列表
  struct objc_protocol_list *protocols         OBJC2_UNAVAILABLE; // 分类所实现的协议列表
}
  • 如果说非要给分类添加属性呢?
    如果非要添加属性,可以。在编译的时候,编译器也不会报错。但是在运行的时候,编译器会崩溃,编译器会说找不到setXX的方法。其实还是那个问题,分类的结构体中没有属性列表这一项,就算你用了@property的属性,系统也不会给你自动生成settergetter方法。

  • 如果用.m文件中强制用@synthesize来生成settergetter方法呢?
    很遗憾,编译器会直接告诉你不可以这样做。哈哈哈,反正就不是不可以。

  • 如果我手动去实现settergetter方法呢?
    完全可以。

//运行时实现setter方法
- (void)setNameWithSetterGetter:(NSString *)nameWithSetterGetter {
        objc_setAssociatedObject(self, &nameWithSetterGetterKey, nameWithSetterGetter, OBJC_ASSOCIATION_COPY);
}

//运行时实现getter方法
- (NSString *)nameWithSetterGetter {
    return objc_getAssociatedObject(self, &nameWithSetterGetterKey);
}

但是,你也只是用点语法来访问这个变量。如果换成用下划线的方式来访问,照样崩溃。


扩展(Extension)


什么是扩展:

扩展是分类的一种特殊形式,扩展是没有名字的分类。有的人也成匿名分类。
扩展通常定义在文件的.m中,不能分开。


扩展可以干什么:

扩展中可以声明:实例变量、属性、方法。并且声明的内容都是私有的,只能在.m文件中使用。


怎么创建扩展:
  • 方式一:

    其实,扩展我们每天都在用,算得上我们最熟悉的陌生人了。
    比如,你新创建的一个工程。在默认的ViewController文件,.h文件有一个@interface ViewController (),而.m文件也有一个@interface ViewController ()。其实,.m文件这个@interface ViewController ()就是扩展,本类的扩展。自己创建的类,如果没有类的扩展,那么就手动在.m文件里面添加即可。

  • 方式二:
    Command+N–>Objective-C File–>File Type:Extension(Class对应你的类)–>声明内容–>然后在你原来的类引入这个文件,就直接用刚才声明的内容了。


总结:

  • 分类中,原则上只能增加方法,不能添加属性
  • 扩展既可以添加属性,也可以添加方法。
  • 扩展中声明的方法没被实现,编译器会报警,但是分类中的方法没被实现编译器是不会有任何警告的。这是因为扩展是在编译阶段被添加到类中,而分类是在运行时添加到类中。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值