分类(类别/Category)与 类扩展(Extension)_weixin_30289831的博客-程序员秘密

一、分类(类别/Category)

1、适用范围

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

@implementation 主类类名(分类类名)

@end

 

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

     调用方法时,只需要向主类引用发送消息即可。
 
3、注意事项
  • 分类中方法的优先级比原来类中的方法高,也就是说,在分类中重写了原来类中的方法,那么分类中的方法会覆盖原来类中的方法
  • 分类中只能声明方法,不能添加属性变量,在运行时分类中的方法与主类中的方法没有区别
  • 通常来讲,分类定义在.h文件中,但也可以定义.m文件中,此时分类的方法就变成私有方法
4、如何使用
     定义PYJViewController类的分类
     “ PYJViewController+Category Controller.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

 

 

转载于:https://www.cnblogs.com/pengyunjing/p/5908460.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30289831/article/details/96644857

智能推荐

WebRTC 学习之 WebRTC 简介_weixin_30763455的博客-程序员秘密

本文使用的WebRTC相关API都是基于Intel Collaboration Suite for WebRTC的。相关文档链接:https://software.intel.com/sites/products/documentation/webrtc/android/index.html1.什么是WebRTC我们都知道浏览器本身不支持相互之间建立信道进行通信,都需要通过...

DTS文件详解,DTS文件解析_九月天-深圳专业软硬件开发的博客-程序员秘密

一.什么是DTS?为什么要引入DTS?DTS即Device Tree Source 设备树源码, Device Tree是一种描述硬件的数据结构,它起源于 OpenFirmware (OF)。在Linux 2.6中,ARM架构的板极硬件细节过多地被硬编码在arch/arm/plat-xxx和arch/arm/mach-xxx,比如板上的platform设备、resource、i2c_board_info、spi_board_info以及各种硬件的platform_data,这些板级细节代码对内核来讲只不

gxhr API 常见用法_node2017的博客-程序员秘密

这里是介绍我们项目常见的XMLHttpRequest异步请求的用法,先来封装一下,让它和jquery ajax使用差不多,封装的文件为gxhr.js,在github上https://github.com/liuxg2013/gxhr/欢迎点赞,下面看看用法??get方式提交数据window.gxhr({ url : "/whats/task/xmlHttpRequest

CTFbugku--菜鸟初学_weixin_30888027的博客-程序员秘密

1.首先打开这个图片2.用记事本打开这个图片3.发现文件的结果有一段unicode代码,然后通过在线转码 转换成ASCII码第一个CFT题就这样解决了O(∩_∩)O转载于:https://www.cnblogs.com/baifan2618/p/7545804.html...

Linux内核运行时错误:general protection fault_SweeNeil的博客-程序员秘密

最近帮师兄做内核实验,错误不断,由于是修改的内核代码,所以经常遇到错误排查起来都比较麻烦,刚解决了一个问题下一个问题就又出现了。直接上新问题的描述:general protection fault这是通过dmesg打印出的保存信息,具体报错内容如下:[ 133.160958] general protection fault: 0000 [#1] SMP PTI……[ 133...

阿里月薪35k的B端产品经理,到底要懂多少业务?_王海638的博客-程序员秘密

你,为什么想要成为产品经理?是想像乔布斯、张小龙那样改变世界,影响亿万人生活?还是想拿高薪、期权,借公司上市实现财富自由?亦或是想获得一份指点江山、挥斥方遒的工作?抱歉,上述所说的都不是产...

随便推点

我的WCF之旅(1):创建一个简单的WCF程序(转载)_weixin_30239339的博客-程序员秘密

为了使读者对基于WCF的编程模型有一个直观的映像,我将带领读者一步一步地创建一个完整的WCF应用。本应用功能虽然简单,但它涵盖了一个完整WCF应用的基本结构。对那些对WCF不是很了解的读者来说,这个例子将带领你正式进入WCF的世界。在这个例子中,我们将实现一个简单的计算服务(CalculatorService),提供基本的加、减、乘、除的运算。和传统的分布式通信框架一 样,WCF本质上提供一个...

数学建模学习笔记(9)多元线性回归分析(非常详细)_时间序列数据怎么做回归分析_北岛寒沫的博客-程序员秘密

逐步回归可以用于解决多重共线性问题。逐步回归可以分为向前逐步回归和向后逐步回归两种具体算法。

查看linux是否存在脏牛漏洞,脏牛Linux本地提权漏洞(CVE-2016-5195)_相月十久的博客-程序员秘密

漏洞编号:CVE-2016-5195漏洞名称:脏牛(Dirty COW)漏洞危害:低权限用户利用该漏洞技术可以在全版本Linux系统上实现本地提权影响范围:Linux内核&gt;=2.6.22(2007年发行)开始就受影响了,直到2016年10月18日才修复。一、检查内核版本通过uname -a 命令,查看内核版本:主流发行版修复之后的内核版本,如果你的内核版本低于列表里的版本,表示还存在脏牛漏洞...

slurm srun提示Job credential expired证书过期_DaHeiBuHei的博客-程序员秘密

报错如图,解决办法:将计算节点与主节点时间设置成一样,我错了几分钟,坑爹的,提示太不明显了,百度还搜不到这个问题,困扰了我好几天,结果周六晚上刷抖音偶然刷到一位HPC的大神,进了微信群请教,好家伙直接秒解决,果断宣传一波,想进群的私聊哟!...

Qt 技术探索之一:Qt 官方 demo 之 Image Composition Example(图片合成)_qt中addop函数_Defonds的博客-程序员秘密

Qt 图片合成例子源码下载        本文取材自 Qt4.5 的官网 Qt Examples -> Painting -> Image Composition。本 demo 主要演示了在 Qt 中是如何选用合成模型将不同的图片合成在一起的。通过本 demo ,我们可以掌握 Qt 中拼接图片、合成图片、组合图片、制造图片以及给图片换背景等实际开发中需要的图片处理技术。  

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 6(offset:6).state_闽农的博客-程序员秘密

如果你在界面中使用了RecyclerView,并且添加了上拉加载和下拉刷新的功能的话,一定对这个异常不会陌生。因为这个异常就时常发生在刷新清除数据的时候,刚好上拉加载的也调用了notifyDataSetChange();然后就会跑出如下异常:java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item