一、分类(类别/Category)

1、适用范围

     当你已经封装好了一个类(也可能是系统类、第三方库),不想在改动这个类了,可是随着程序功能的增加需要在类中增加一个方法,这时我们不必修改主类,只需要给你原来的类增加一个分类。
     将一个大型的类拆分成不同的分类,在不同分类中实现类别声明的方法,这样可以将一个类的实现写到多个.m文件中,方便管理和协同开发。
     分类中的方法可以只声明,不实现,所以在协议不支持可选方法的时候(协议现在已经支持可选方法),通常把分类作为非正式协议使用。
 
2、语法格式
     文件中的语法
@interface 主类类名(分类类名)
//不可以定义成员属性
@end @implementation 主类类名(分类类名) @end

文件名通常为:主类名+分类名

     调用方法时,只需要向主类引用发送消息即可。
 
3、注意事项

  • 分类中方法的优先级比原来类中的方法高,也就是说,在分类中重写了原来类中的方法,那么分类中的方法会覆盖原来类中的方法
  • 分类中只能声明方法,不能添加属性变量,在运行时分类中的方法与主类中的方法没有区别
  • 通常来讲,分类定义在.h文件中,但也可以定义.m文件中,此时分类的方法就变成私有方法
4、如何使用
     定义PYJViewController类的分类
     “PYJViewController+CategoryController.h”文件:
@interface PYJViewController (CategoryController)
- (void)test;
@end

“PYJViewController+CategoryController.m”文件:

@implementation PYJViewController (CategoryController)
- (void)test {
NSLog(@"这是一个分类");
}
@end

5、虽然不能在分类(类别)中定义成员属性,但是有办法也可以让它支持添加属性和成员变量

Category是Objective-C中常用的语法特性,通过它可以很方便的为已有的类来添加函数。但是Category不允许为已有的类添加新的属性或者成员变量。     
    一种常见的办法是通过runtime.h中objc_getAssociatedObject / objc_setAssociatedObject来访问和生成关联对象。通过这种方法来模拟生成属性。

“NSObject+SpecialName.h”文件:

@interface NSObject (SpecialName)
@property (nonatomic, copy) NSString *specialName;
@end

“NSObject+SpecialName.m”文件:

#import "NSObject+Extension.h"
#import <objc/runtime.h>
static const void *SpecialNameKey = &SpecialNameKey;
@implementation NSObject (SpecialName)
@dynamic specialName; - (NSString *)specialName {
//如果属性值是非id类型,可以通过属性值先构造OC的id对象,再通过对象获取非id类型属性
return objc_getAssociatedObject(self, SpecialNameKey);
} - (void)setSpecialName:(NSString *)specialName{
//如果属性值是非id类型,可以通过属性值先构造OC的id对象,再通过对象获取非id类型属性
objc_setAssociatedObject(self, SpecialNameKey, specialName, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
} @end

二、类扩展

1、适用范围

     扩展是分类的一种特殊形式。
 
2、语法格式
     @interface 主类类名()
     @end
     扩展通常定义在主类.m文件中,扩展中声明的方法直接在主类.m文件中实现。
 
3、注意事项
  • 扩展中可以声明实例变量,可以声明属性
  • 因为扩展通常定义在主类的.m文件中,所以扩展声明的方法和属性通常是私有的
4、分类和扩展的区别
     分类是不可以声明实例变量,通常是公开的,文件名是:主类名+分类名.h
     扩展是可以声明实例变量,是私有的,文件名为:主类名_扩展标识.h,在主类的.m文件中#import该头文件
 
5.如何使用

    定义 PYJViewController类的扩展
    方式1、以单独的文件定义
    “PYJViewController_ExtensionController.h”文件:
#import"PYJViewController.h"

@interface PYJViewController ()
@property(nonatomic, copy)NSString *stringExtension;
- (void)testExtension;
@end

方式2、在主类的.m文件中定义

    “PYJViewController.m”文件:

#import"PYJViewController.h"

@interface PYJViewController ()
@property(nonatomic, copy)NSString *stringExtension;
- (void)testExtension;
@end

在主类的.m文件中实现扩展定的方法:

@implementation PYJViewController
- (void)testExtension {
self.stringExtension = @"给扩展里面定义的属性字符串赋值";
NSLog(@"定义的属性String是:%@", self.stringExtension);
}
@end

分类(类别/Category)与 类扩展(Extension)的更多相关文章

  1. 分类(Category)的本质 及其与类扩展(Extension) /继承(Inherit)的区别

    1.分类的概念 分类是为了扩展系统类的方法而产生的一种方式,其作用就是在不修改原有类的基础上,为一个类扩展方法,最主要的是可以给系统类扩展我们自己定义的方法. 如何创建一个分类?↓↓ ()Cmd+N, ...

  2. iOS分类(category),类扩展(extension)—史上最全攻略

    背景: 在大型项目,企业级开发中多人同时维护同一个类,此时程序员A因为某项需求只想给当前类currentClass添加一个方法newMethod,那该怎么办呢? 最简单粗暴的方式是把newMethod ...

  3. 类目(category) - 类扩展(extension) 区别

    说明: 方法,属性或变量:   类别只能添加方法,不能添加属性(理论上,但可以通过runtime的关联添加). 扩展可以添加方法和实例变量或属性,实例变量默认@private类型.扩展是类别的一个特例 ...

  4. 关于iOS 类扩展Extension的进一步理解

    很多人可能会问  iOS的分类和扩展的区别,网上很多的讲解,但是一般都是分类讲的多,而这也是我们平常比较常用的知识:但是,对于扩展,总觉得理解的朦朦胧胧,不够透彻. 这里就讲一下我自己的理解,但是这个 ...

  5. 类扩展Extension

    延展(Extension):在本类里声明私有方法. 1:延展定义的方法是在implemetation中. 2:声明的方法是私有方法. 3:延展中声明的方法可以不实现. #import "Ho ...

  6. iOS中 分类(category)与扩展(Extension)的区别?

    1.分类(category)的作用 (1).作用:可以在不修改原来类的基础上,为一个类扩展方法.(2).最主要的用法:给系统自带的类扩展方法. 2.分类中能写点啥? (1).分类中只能添加“方法”,不 ...

  7. OC分类(类目/类别) 和 类扩展 - 全解析

    OC分类(类目/类别) 和 类扩展 - 全解析   具体见: oschina -> MyDemo -> 011.FoundationLog-OC分类剖析 http://blog.csdn. ...

  8. OC-ARC,类扩展,block

    总结 标号 主题 内容 一 autorelease autorelease基本概念/自动释放池/autorelease基本使用 二 autorelease注意事项 注意点/应用场景 三 ARC 什么是 ...

  9. iOS中的分类(category)和类扩展(extension)

    今天在研究swift的时候看到了分类和扩展.这是两个十分重要有用的功能,但是之前用的不多,没有深入了解过,在今天就从头理一遍. 一.分类(Category): 概念: 分类(Category)是OC中 ...

随机推荐

  1. 对MySQL数据类型的认识

    简述 良好的逻辑设计和物理设计是高性能系统的基石,比如反范式设计可以加快某些类型的查询同时也会影响另外一些类型的查询效率,所以我们必须重视Mysql对于数据库的设计(本文主要讲述表字段类型对于数据库性 ...

  2. 程序包com.sun.istack.internal不存在

    添加一下依赖 <!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-impl --><dependency> ...

  3. Gradle 引入本地定制 jar 包,而不使用坐标下载 jar 包的方法

    第 1 步:创建文件夹,拷贝 jar 包 在自己的 Gradle 项目里建立一个名为 “libs” (这个名字可以自己定义,不一定非要叫这个名字)的文件夹,把自己本地的 jar 包拷贝到这个文件夹中. ...

  4. zabbix 邮件报警

    一.设置sendmail 安装sendmail yum install -y sendmail systemctl start sendmail.service 配置 cd  /usr/lib/zab ...

  5. angularjs Dom方式访问疑似可以访问ifame结构项目

    一.定位需要访问控制器元素 var currObj = document.querySelector('[ng-controller="munuListCtrl"]'); 或者 v ...

  6. 使用axis2构建webservice

    axis2是可以实现webservice的一个插件,使用这个插件可以发布webservice 1:可以使用这个插件来发布webservice,可以看网址:http://clq9761.iteye.co ...

  7. GoLang激活码

    虽然行为不太好,但是购买的话实在是比较贵. 进入软件,Help-Register,选择License Server,输入 http://idea.youbbs.org 激活即可.

  8. Linux常用命令.rpm

    1.安装: rpm -ivh 包全名(查询依赖网址:http://www.rpmfind.net) -i(install):安装 -v(verbose):显示详细信息 -h(hash):显示进度 -- ...

  9. Tkinter Button按钮组件如何调用一个可以传入参数的函数

    这里我们要使用python的lambda函数,lambda是创建一个匿名函数,冒号前十传入参数,后面是一个处理传入参数的单行表达式. 调用lambda函数返回表达式的结果. 首先让我们创建一个函数fu ...

  10. Ajax-04 jQuery Ajax 常用操作

    jQuery jQuery 其实就是一个JavaScript的类库,其将复杂的功能做了上层封装,使得开发者可以在其基础上写更少的代码实现更多的功能. jQuery Ajax a.概述 jQuery 不 ...