谈谈Category和Extension

作者: 夜3033 | 来源:发表于2016-07-18 10:25 被阅读1271次

开篇

在平时的项目中时常可以用到Category,在研究别人的代码时遇见Category和Extension也是一件极其平常的事情。还记得当我第一次见到这种写法的时候我的内心是崩溃的。


示例1.png

一串的"+"号,这是什么鬼简直颠覆我的三观好么,完全的一头雾水,经过慢慢的研究才发现了他的好处,原来还可以这样玩,不错不错。但是接着又发现一个问题Extension是什么呢,持续的懵逼中...今天我们就来谈谈Category和Extension 究竟有何神奇之处。

效果简单展示

AppDelegate_m.png AppDelegate_m 2.png

我们来看一下上面的两张appdelegate.m的内容,两个简单的小工程中,一个的内容中有上百行甚至几百行的代码,另一个却只有几行,我们先不说Category的别的功能单单是代码的分块,清晰条理和代码的可读性上就值得我们研究一番更何况他不止于此呢。

创建方法

既然那么好用我们怎么创建他呢,话不多说上图片。


创建1.png 创建2.png

原理

Category
  • 有两方面局限性:
    (1)无法向类中添加新的实例变量,类别没有位置容纳实例变量。
    (2)名称冲突,即当类别中的方法与原始类方法名称冲突时,类别具有更高的优先级。类别方法将完全取代初始方法从而无法再使用初始方法。
  • 主要有3个作用:
    (1)可以将类的实现分散到多个不同文件或多个不同框架中,方便代码管理。也可以对框架提供类的扩展(没有源码,不能修改)。
    (2)创建对私有方法的前向引用:如果其他类中的方法未实现,在你访问其他类的私有方法时编译器报错这时使用类别,在类别中声明这些方法(不必提供方法实现),编译器就不会再产生警告
    (3)向对象添加非正式协议:创建一个NSObject的类别称为“创建一个非正式协议”,因为可以作为任何类的委托对象使用。

Extension

  • Extension常被称为是匿名的Category(比如:在字符串中类扩展extension,添加的属性str1和show方法都是私有的,只能在String类中可以访问得到
    )
  • 用于给类添加新方法,但只作用于原始类,不作用于subclass
  • 只能对有implementation源代码的类写Extension,对于没有implementation源代码的类,比如framework class,是不可以的
    Extension可以给原始类添加新方法,以及新属性

他们的主要区别是:

1、形式上来看,extension是匿名的category。
2、extension里声明的方法需要在mainimplementation中实现,category不强制要求。
3、extension可以添加属性(变量),category不可以。

使用举例

个人感觉在项目中Category的使用还是比较多的现在举个简单的代码例子

UIButton_GSbutton_h.png

在工程中创建两个Category的分类,一个是UIButton的一个是appdelegate的。在.h文件中按钮的类暴露的方法如图所示。我们在.m中实现它,如下图

UIButton_GSbutton_m.png

类的方法实现之后我们导入类名,来调用方法。

按钮创建.png

我们直接调用我们自己创建的方法,给予他设置名称和已经确定的名称颜色和背景,在大规模使用中可以减少我们的代码量。
同样的道理我们也可以在appdelegate中创建分类,实现自己想要的功能实现代码的分块。

AppDelegate_GSCategory_h.png

同时通过图中划线的方法我们可以获取函数中的相应参数,以供相应的方法中使用,比如极光推送需要的application和launchoptions ,然后在.m文件中实现自己需要的方法就可以对代码进行分块了。

AppDelegate_m.png

这个图为appdelegate中使用Category以后的代码形式,是不是简洁了许多。

后记

文中的内容仅仅是自己的一点想法,有错误的地方谢谢各位的指出,以后有时间会继续分享一些Category和Extension的认识。

相关文章

网友评论

  • 23240449cd79:其实 Category 是可以添加成员变量的,详情可看下喵神的这篇文章: http://swifter.tips/associated-object/
    自己添加的方法,有个前缀 “GS_”来以防与其他 framework 冲突,这其实是必须的。难保会不会刚好与其他 framework 用了相同的方法名。@iOS_愛OS
    另外,有个小小的建议,添加的方法名,最好统一用驼峰命名法,保持代码风格的一致。可以参照 Masonry 的做法 https://github.com/SnapKit/Masonry
    以上是我个人的想法,欢迎讨论。 :smile:
  • iOS_愛OS:赞一个,有个问题哈
    ,你的方法以 GS_开头有什么特殊意思么
    iOS_愛OS:@夜3033 这样哈,懂了
    夜3033: @iOS_愛OS 没有,姓名首字母缩写。。。

本文标题:谈谈Category和Extension

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