Categories

Categories框架

catgory 容许你为一个已经存在的类增长方法----甚至是一个你没有source的类。对象

Categories是一种强大的特性,它容许你直接扩展类的功能,而不须要使用子类的方法来扩展。继承

 

须要注意的是category不能够为要扩展的类声明额外的实例变量;它只能包含方法。然而,全部在类的做用域里的实例变量也在category的做用域里。前面的实例变量指的是类里能声明过的实例变量,@private的也不例外。作用域

使用categories,你能够把你本身的类的实现方法分布在几个不一样的文件里。 为一个类增长categories的数量是没有限制的,可是每个category 的名字必需要是不相同的,并且应该声明和定义一个不一样的方法集。开发

How You Can Use Categories编译

使用categories的方式有不少:class

  • 扩展一个其它实施者定义的类

     例如,你能够为Cocoa frameworks里的类增长方法。增长的方法会被子类继承并且在运行时也不会和原始的方法有任何不一样。变量

  • 做为子类的一个替代方式

       不须要定义一个子类来扩展已有的类,经过category你能够直接为类添加方法。例如,你能够为NSArray和其它的Cocoa classes添加categories.与添加子类的方式来比,你不须要你扩展的类的源代码。扩展

  • 把实现一个新类的方法分布在多个源文件里

     例如,你能够把一个很大的类的方法分组到几个categories里,而后把每一个     category放在本身的文件里。当以这种方式使用时,categories在不少方面对开发过程都是有帮助的:配置

1.提供一个简单的方式来组合相关的方法。被定义在不一样的类里的类似的方法能够被保存在同一个源文件里。

2.当一个类是由多个开发者共同定义的时候,能够简化大类的管理。

3.为一个很是大的类的增量编译提供方便。

4.提升经常使用方法的本地参考。

5.能够根据不一样版本的程序配置不一样的类,而无需为不一样版本保持相同的源代码。

虽然Objective-C语言目前容许使用category来经过重载继承的类的方法或者甚至是类文件中的方法,可是这种作法是被强烈反对的。category不是子类的替代品。使用category 来重载

方法有不少重大的缺陷:

  • 当category 重载一个从父类继承过来的方法,一般能够经过super关键字来调用父类的实现方法。然而,若是category重载一个扩展类自己存在的方法,就没有唤醒原始实现方法的办法了。
  • 同一个类的category不能声明重载这个类的另外一个category中声明的方法。这一点很是的重要,由于不少Cocoa类也是经过使用categories来实现的。一个你试图重载的框架中定义的方法可能自己就已经在一个category被实现了,若是你这样作了,极可能使用得前面的category的方法的实现失效。
  • 一些category methods的存在可能会致使整个框架的行为发生变化。

     例如,若是你在NSObject的一个category中重载windowWillClose:委托方法,在你的程序里全部窗口的委托将会使用category方法来回应;全部NSWIndow实例的行为都会改变。你为一个框架类增长的Categories可能会致使行为上很神秘的变化和程序的崩溃。

Categories of the Root Class

Category 能够为任何的类添加方法,其中也包括root class。添加到NSObject类上的方法对于全部与你的代码相关联的类都是可用的。有时候为root class添加方法是很是有用的,可是它也是很是危险的。虽然从表面上看起来category所作出的修改能够被很好的理解,并且影响也是有限的,可是继承的机制使得它有了一个普遍的做用域。你可能会对你程序里不可见的类作出意想不到的修改;你可能会对你正在作的事会产生的结果一无所知。甚者,当对你修改过什么一无所知的人在你的程序上工做时,他们对于他们正在作的事也不会有一个充分的了解。

另外,当你为root class实现方法时有两点须要记住:

  • 发送消息给super是非法的(由于NSObject没有超类)
  • 类的对象能够执行root class中定义的实例方法

正常来讲,类对象只能执行类方法。可是root class中定义的实例方法是一个特例。它们定义了一个类,在运行时系统中的全部对象都继承这个类。类对象是彻底成熟的对象,它须要共享同一个类。

 

这个特性意味着你为NSObject类在category定义的实例方法不只要能被实例对象执行,并且也要能被类对象执行。例如:在方法体中,self可能表明一个类对象,也多是类的一个实例。

相关文章
相关标签/搜索