本文转载Keefo

Objective-C的Object-oriented programming特性提供subclass和category这2个比较非常重要的部分。subclass应该反复被各种编程书籍介绍过。它是oop继承特性的关键语法,它给类添加了延续并且多样化自己的方法。可以说没有继承就没有oop这玩意。而category相对于subclass就不那么出名了。其实category思想出世于smalltalk,所以它不能算是一个新生事物。 
 
先说一下这2个特性最主要的区别。简单可以这么理解,subclass体现了类的上下级关系,而category是类间的平级关系。

  
 
如上图所示,左侧是subclass,可以看到class, subclass1, subclass2是递进关系。同时下面的子类完全继承父类的方法,并且可以覆盖父类的方法。subclass2拥有function1,function2,function3三个函数方法。function1的执行代码来自subclass1, function2的执行代码来自于subclass2。 
 
右侧是category。可以看到,无论如何扩展类的category,最终就只有一个类class。category可以说是类的不同方法的小集合,它把一个类的方法划分成不同的区块。请注意观察,每个category块内的方法名称都没有重复的。这正是category的重要要求。 
 
经过上面简单解释了解了这2点的基本区别,现在深入说一下category。 
 
在Objective-c语言设计之初一个主要的哲学观点就是尽量让一个程序员维护庞大的代码集。(对于庞大的项目‘原则’和‘协议’是非常重要的东西。甚至编写良好的文件名都是非常重要的开发技巧)根据结构化程序设计的经验出发,把一个大块代码划分成一些小块的代码更便于程序员管理。于是objc借用了smalltalk的categories概念。允许程序员把一系列功能相近的方法组织到一个单独的文件内,使得这些代码更容易识别。 
 
更进一步的,和c,c++这种静态语言相比。objc把class categories功能集成到了run-time里面。因此,objc的categories允许程序员为已经存在的类添加新的方法而不需要重新编译旧的类。一旦一个category加入,它可以访问该类所有方法和实例变量,包括私有变量。 
 
category不仅可以为原有class添加方法,而且如果category方法与类内某个方法具有同样的method signature,那么category里的方法将会替换类的原有方法。这是category的替换特性。利用这个特性,category还可以用来修复一些bugs。例如已经发布的Framework出现漏洞,如果不便于重新发布新版本,可以使用category替换特性修复漏洞。另外,由于category有run-time级别的集成度,所以使得cocoa程序安全性有所下降。许多黑客就是利用这个特性(和posting技术2)劫持函数、破解软件,或者为软件增加新功能。一个很典型的例子就是,我发布的QQ表情管理器。 
 
值得注意的一点是,由于一个类的categories之间是平级关系。所以如果不同categories拥有相同的方法,这个调用结果是未知的。所以:

引用
Category methods should not override existing methods (class or instance).  
Two different categories implementing the same method results in undefined behavior 

Objc中Categories有其局限的部分,就是你不能为原有的class添加变量,只能添加方法。当然方法里可以添加局部变量。在这个局限基础上就有其它语言做了进一步改进,例如TOM语言就为Categories增加了添加类变量的能力。 
 
总上所属,如果你开发时候遇到无论如何都需要为类添加变量的情况,最好的选择就是subclass。相反如果你只希望增加一些函数簇。Categories是最好的选择。 
 
并且我个人给大家的建议是,每个Cocoa程序员都应该收集整理自己的一套NS类函数的Categories扩展库。这对你今后程序开发效率和掌控情况都有很大提高。

OC特有语法-分类(category)的更多相关文章

  1. OC的特有语法-分类Category、 类的本质、description方法、SEL、NSLog输出增强、点语法、变量作用域、@property @synthesize关键字、Id、OC语言构造方法

    一. 分类-Category 1. 基本用途:Category  分类是OC特有的语言,依赖于类. ➢ 如何在不改变原来类模型的前提下,给类扩充一些方法?有2种方式 ● 继承 ● 分类(Categor ...

  2. OC特有语法:分类category,给NSString增加方法计算字符串中数字的个数

    1:分类的使用场景:想对一个类,扩充一些功能,而又不改变原来类的模型,也不用继承,这时OC中的特有语法:分类可以做到: 当然分类也是一个类,也需要声明和实现,声明在.h文件中,实现在.m文件中,格式如 ...

  3. oc特有语法

    分类 问题 1.什么是分类? 就是把一个类的功能,分出一部分来放在一个独立的文件中 2.分类的语法是什么样的? @interface Person(SuperMan) 3.分类与类是什么关系? 分类依 ...

  4. OC分类(Category)

    Category 分类 ,又称为类别.类目 概念 Category有多种翻译:分类.类别.类目(一般叫分类的多) Category式OC特有的语法,其他语言没有的语法(类似于C#语言中的"扩 ...

  5. OC中分类(Category)和扩展(Extension)

    1.分类的定义 category是Objective-C 2.0之后添加的语言特性,中文也有人称之为分类.类别.Category的主要作用是为已经存在的类添加方法.这个大家可能用过很多,如自己给UIC ...

  6. OC中的特有语法

    一. 分类-Category 1. 基本用途 如何在不改变原来类模型的前提下,给类扩充一些方法?有2种方式 l 继承 l 分类(Category) 2. 格式 分类的声明 @interface 类名  ...

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

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

  8. 从C#到Objective-C,循序渐进学习苹果开发(3)--分类(category)和协议Protocal的理解

    本随笔系列主要介绍从一个Windows平台从事C#开发到Mac平台苹果开发的一系列感想和体验历程,本系列文章是在起步阶段逐步积累的,希望带给大家更好,更真实的转换历程体验.本文继续上一篇随笔<从 ...

  9. iOS开发——OC篇&OC高级语法

    iOS开发高级语法之分类,拓展,协议,代码块详解 一:分类 什么是分类Category? 分类就是类的补充和扩展部分 补充和扩展的每个部分就是分类 分类本质上是类的一部分 分类的定义 分类也是以代码的 ...

随机推荐

  1. CentOS6.7 常用操作命令

    centos 安装py环境 1.安装wget工具: yum install wget 2.安装Python-2.7.8: wget --no-check-certificate https://www ...

  2. POJ 2318 TOYS/POJ 2398 Toy Storage

    计算几何终于开坑了... 叉积+二分. #include<iostream> #include<cstdio> #include<cstring> #include ...

  3. 读取xml文件信息

    static void Main(string[] args) { XmlTextReader reader = new XmlTextReader(@"D:\zy\visual studi ...

  4. css3圈圈进度条

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  5. HTML5 为什么这么火?

    H5是超文本语言HTML的第五次修订,是近几年来Web标准巨大的飞跃. 以往,我们在Web上还只是上网看一些基础文档,但现在,Web是一个内涵非常丰富的平台.和以前版本不同的是,HTML5并非仅仅用来 ...

  6. 附加数据库报错:无法打开物理文件 XXX.mdf",操作系统错误 5:"5(拒绝访问。)"

    今天在附加数据库的时候出现如图报错信息: 无法打开物理文件 XXX.mdf",操作系统错误 5:"5(拒绝访问.)"错信息如图:(是不是远程服务器数据库附加出现只读那个情 ...

  7. vim+ctags+cscope工具

    最近在看一个开源的项目,突然发现在Linux上不知道有什么方便的工具来看开源代码.以前,在Windows上用VS2010集成开发环境,对于任意一个函数直接有快捷键跳转到函数定义处.可现在在Linux上 ...

  8. Mysql创建函数出错

    目前在项目中,执行创建mysql的函数出错, mysql 创建函数出错信息如下: Error Code: 1227. Access denied; you need (at least one of) ...

  9. 阿里大鱼simplexmlelement object 取值PHP

    SimpleXMLElement Object(    [code] => 15    [msg] => Remote service error    [sub_code] => ...

  10. DEDE数据库修改后台变量

    进行数据库之后找到 dede_sysconfig 这个数据表,然后查找到你要删除的dede教程变量名称. 这样就可以了