Categories

来源:互联网 发布:linux 系统克隆 编辑:程序博客网 时间:2024/05/22 17:22
 Categories
catgory 允许你为一个已经存在的类增加方法----甚至是一个你没有source的类。
Categories是一种强大的特性,它允许你直接扩展类的功能,而不需要使用子类的方法来扩展。

需要注意的是category不可以为要扩展的类声明额外的实例变量;它只能包含方法。然而,所有在类的作用域里的实例变量也在category的作用域里。前面的实例变量指的是类里能声明过的实例变量,@private的也不例外。
使用categories,你可以把你自己的类的实现方法分布在几个不同的文件里。 为一个类增加categories的数量是没有限制的,但是每一个category 的名字必须要是不相同的,而且应该声明和定义一个不同的方法集。
How You Can Use Categories
使用categories的方式有很多:
  • 扩展一个其它实施者定义的类
     例如,你可以为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可能代表一个类对象,也可能是类的一个实例。



  
  

0 0
原创粉丝点击