美文网首页
Category与Extension

Category与Extension

作者: 大白简先生 | 来源:发表于2018-04-11 15:44 被阅读0次

Category

  • 概述:Category是OC2.0之后添加的语言特性,Category又叫类别,分类等,能够在不改变原来类的内容基础上,为类增加一些方法(当然还有大家都知道的,虽然不能以正常方式为类添加属性,但是我们可以通过runtime来动态绑定添加,后面会讲到),除此之外Category还有以下功能
  1. 将类的实现分开写在几个分类里面,这样做的好处是
  • 可以减少单个文件的体积
  • 可以把不用的功能组织在不同的Category里
  • 可以由多个开发者共同完成一个类
  • 可以按需加载想要的Category
  1. 声明私有的方法
  2. 模拟多继承
  • 使用
    既然我们说Category只能为类增加方法,而不能添加属性,那么我们就去创建一个分类文件去验证以下,看看具体是个什么样的情况。

我们创建了一个Student和他的分类Student+Category

@interface Student : NSObject
@property (nonatomic,copy) NSString *age;
@property (nonatomic,copy) NSString *name;
@end
//Student+Category.h
@interface Student (Category)
@property (nonatomic,copy) NSString *schoolName;
@end

我们运行一下,可以发现他编译成功了并且运行成功了,


image image

放开断点发现崩溃了,看错误日志我们知道了没有setSchoolName方法。那么问题来了,既然我们可以在分类中添加属性,但在调用的时候却会奔溃,这是为什么,我们先来看看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; // 分类所实现的协议列表
}

我们看到了什么,我们有发现实例方法列表,类方法类表,协议列表,但是没有属性列表。我们知道在一个类中用 @property 声明属性,编译器会自动帮我们生成 _成员变量名 和setter,getter方法,但是在分类的指针结构体中,根本就要没有属性类表,所以也就不能生成 _成员变量名 和setter,getter方法,因此我们的程序可以编译和运行都成功了,但是一旦有调用这个属性就会奔溃。

解决方案

  • 由于OC是动态语言,方法真正的实现是通过runtime完成的,虽然系统不给我们生成setter/getter,但我们可以通过runtime手动添加setter/getter方法
#import "Student+Category.h"
#import <objc/runtime.h>
static const char *schoolNameKey = "schoolNameKey";
@implementation Student (Category)
- (void)setSchoolName:(NSString *)schoolName{
    objc_setAssociatedObject(self, &schoolNameKey, schoolName, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSString *)schoolName{
    return objc_getAssociatedObject(self, &schoolNameKey);
}
@end
  • 总结
  1. 分类是用于给原有类添加方法的,因为分类的结构体指针中,没有属性列表,只有方法列表。所以< 原则上讲它只能添加方法, 不能添加属性(成员变量),实际上可以通过其它方式添加属性> ;
  2. 分类中的可以写@property, 但不会生成setter/getter方法, 也不会生成实现以及私有的成员变量(编译时会报警告);
  3. 可以在分类中访问原有类中.h中的属性;
  4. 如果分类中有和原有类同名的方法, 会优先调用分类中的方法, 就是说会忽略原有类的方法。所以同名方法调用的优先级为 分类 > 本类 > 父类。因此在开发中尽量不要覆盖原有类;
  5. 如果多个分类中都有和原有类中同名的方法, 那么调用该方法的时候执行谁由编译器决定;编译器会执行最后一个参与编译的分类中的方法。

Extension

  • Extension 是Category的一个特例,类扩展与分类相比只少了分类的名称以及.m文件,他常用的形式不是创建一个单独的文件,而是在实现文件中添加私有的成员变量、属性和方法。比如我们平时在创建一个类的时候我们会在.m文件中添加私有的成员变量、属性和方法,当然我们也可以在.h文件中添加,所以说Extension在我们平时的开发中是最常用的
@interface Student ()
{
    NSString *_core;
}
@property (nonatomic,copy) NSString *teachName;
- (void)study;
@end
  • 总结
  1. Extension的作用是为一个类添加额外的私有成员变量,属性以及方法
  2. 一般的类扩展写到.m文件里

Category和Extension的区别

  1. Category原则中只能增加方法(能添加属性的原因只是通过runtime解决没有setter和getter方法)
  2. Extension不仅可以增加方法,还可以增加属性,只是属性默认的访问权限是 private
  3. Extension中声明的方法没有在.m文件中实现,编译器会报警,但是在Category中的方法没有实现的话编译器是不会有任何警告的。这是因为Extension是在编译阶段添加到类中,而Categor是在运行时添加到类中的
  4. Extension不能像类别那样拥有独立的实现部分,他所声明的方法只能在其对应的类中实现
  5. Extension定义在.m文件的方法是私有的,定义在.h文件的方法是公有的
  6. Extension一般用来隐藏类的私有消息,你必须有一个类的源码才能添加一个类的Extension,所以对于系统一些类,如NSString,就无法添加类扩展,如果只是简单的创建Extension文件是能够创建成功的,但是如果你在文件中添加属性或者方法,在程序中一旦使用了该属性或者方法程序就会崩溃,会报找不到相对应的方法错误信息。

参考资料来源

  1. http://blog.csdn.net/haishu_zheng/article/details/12873151
  2. http://www.imlifengfeng.com/blog/?p=397

相关文章

  • Objective-C 扩展与关联对象

    一、类扩展分析 1.1 category 与 extension category和extension开发中经常遇...

  • 深入分析 Category

    简介 Category 主要作用 Category 与 Class Extension Category 加载时机...

  • iOS Category详解

    Extension详解,及与Category的区别 1、什么是Category? category是Objecti...

  • Objective-C 之Extension

    Objective-C 之Extension class extension:类扩展 类扩展与 category ...

  • UI基础知识

    分类(类别/Category)与类扩展(Extension) 一、分类(类别/Category) 1. 适用范围 ...

  • Swift - 基础之extension

    在swift中,extension与Objective-C的category有点类似,但是extension比起c...

  • Category与Extension

    在Objective-C中,要扩展一个类的方法,首先想到的应该是继承,这是面向对象语言的一个特性。继承可以很方便的...

  • Category与Extension

    1、Extension的基本用法 Extension的创建方法与Category一样,只要在原来选择Categor...

  • extension与category

    1、形式上来看,extension是匿名的category。 2、extension里声明的方法需要在main i...

  • Category与Extension

    Category概述:Category是OC2.0之后添加的语言特性,Category又叫类别,分类等,能够在不改...

网友评论

      本文标题:Category与Extension

      本文链接:https://www.haomeiwen.com/subject/tdmcsxtx.html