iOS类别(Category)与扩展(Extension)

Category在iOS开发中使用非常频繁。尤其是在为系统类进行拓展的时候,我们可以不用继承系统类,直接给系统类添加方法,最大程度的体现了Objective-C的动态语言特性。

#import

@interface NSObject (Category)

- (void)myMethod;

@end

这是一个最简单的Category,作用于NSObject类,给NSObject添加了一个方法。

使用Category需要注意的点:

(1) Category的方法不一定非要在@implementation中实现,也可以在其他位置实现,但是当调用Category的方法时,依据继承树没有找到该方法的实现,程序则会崩溃。

(2) Category理论上不能添加变量,但是可以使用@dynamic 来弥补这种不足。

#import

static const void * externVariableKey =&externVariableKey;

@implementation NSObject (Category)

@dynamic variable;

- (id) variable

{

return objc_getAssociatedObject(self, externVariableKey);

}

- (void)setVariable:(id) variable

{

objc_setAssociatedObject(self, externVariableKey, variable, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

-----------------------------------------------------------------------------------------

Extension非常像是没有命名的类别。

@interface MyClass : NSObject

@property (retain, readonly) float value;

@end

//一般的时候,Extension都是放在.m文件中@implementation的上方。

@interface MyClass ()

@property (retain, readwrite) float value;

@end

使用Extension需要注意的点:

(1) Extension中的方法必须在@implementation中实现,否则编译会报错。

无 论一个类设计的如何完美,都不可避免的会遇到没有预测到的需求,那怎么扩展现有的类呢?当然,继承是个不错的选择。但是Objective-C提供了一种 特别的方式来扩展类,叫Catagory,可以动态的为已经存在的类添加新的行为。这样可以保证类的原原来的基础上,较小的改动就可以增加需要的功能。使 用Category对类进行扩展时,不需要访问其源代码,也不需要创建子类,这样我们可以扩展系统提供的类。Category使用简单的方式,实现了类的相关方法的模块化,把不同的类方法分配到不同的分类文件中。

通过一个简单的例子看看Category如何使用。

现在我们有一个类叫MyClass

  1. #import
  2. @interface MyClass : NSObject
  3. -(void) myPrint;
  4. @end
  1. #import "MyClass.h"
  2. @implementation MyClass
  3. -(void) myPrint{
  4. NSLog(@"myPrint 调用了");
  5. }
  6. @end

它有一个实例方法:myPrint,待会我们可以在扩展后调用它

好了,有了上面的MyClass后,我们要在不增加子类,不修改MyClass类的情况下增加一个HelloWorld的方法,怎么添加呢?只需添加两个文件MyClass+HelloWorld.h  和 MyClass+HelloWorld.m。

在声明文件和实现文件中用“()”把Category的名称括起来。原类名+Category”的这是约定的文件命名方式。

看看这两个文件怎么实现,在Xcoed上按Command+N,新建文件,选择Objective-C category方式创建类,这样Xcode会自动帮你创建约定命名方式的文件。


Category on的类是MyClass,选对了哦

这样Xcode就帮你创建了MyClass+HelloWorld.h  和 MyClass+HelloWorld.m这两个文件了。

那么我们现在添加一个HelloWorld方法。看看实现后的代码如下:

  1. #import "MyClass.h"
  2. @interface MyClass (HelloWorld)
  3. -(void)HelloWorld;
  4. @end
  1. #import "MyClass+HelloWorld.h"
  2. @implementation MyClass (HelloWorld)
  3. -(void)HelloWorld{
  4. NSLog(@"你好 伦敦奥运!");
  5. }
  6. @end

在main中调用

  1. MyClass *myclass = [[[MyClass alloc]init]autorelease];
  2. [myclass HelloWorld];
  3. [myclass myPrint];

运行打印结果:

  1. 2012-08-09 11:24:16.697 objectiveC[16053:403] 你好 伦敦奥运!
  2. 2012-08-09 11:24:16.699 objectiveC[16053:403] myPrint 调用了

那的Category的使用场景有那些呢:
1、类包含了很多个方法实现,而这些方法需要不同团队的成员来实现
2、当你在使用基础类库中的类时,你不想继承这些类而只想添加一些方法时。
 
Category能实现上面的需求,当然也有使用Category是需要注意的问题:
1、Category可以访问原始类的实例变量,但不能添加实例变量,如果想添加变量,那就通过继承创建子类来实现。
2、Category可以重载原始类的方法,不大不推荐这么做,这样会覆盖掉原始类的方法。如果确实要重载,那就通过继承创建子类来实现。
3、和普通接口有所区别的是,在Category的实现文件中的实例方法只要你不去调用它你可以不用实现所有声明的所有方法。

iOS类别(Category)的更多相关文章

  1. iOS类别(Category)与扩展(Extension)-b

    苹果的官方文档 Category在iOS开发中使用非常频繁.尤其是在为系统类进行拓展的时候,我们可以不用继承系统类,直接给系统类添加方法,最大程度的体现了Objective-C的动态语言特性. #im ...

  2. iOS类别(Category)和扩展(Extension,匿名类)

    Category在iOS在开发常用. 特别是对于系统扩展上课时间.我们不能继承系统类.直接添加到系统类方法,最大程度上体现Objective-C动态语言特征. #import @interface N ...

  3. ios 类别(category)

    定义 类别(category)是Objective-C语言的新特性,为现有的类添加新方法的方式.局限性:1.无法添加新的实例变量.2.与类本身的方法名称冲突.当名称冲突时,类别具有更高的优先级.作用: ...

  4. 类别(Category)与扩展(Extensions)

    一.类别(Category) 类别(Category)是一种可以为现有的类(包括类簇:NSString...,甚至源码无法获得的类)添加新方法的方式无需从现有的类继承子类.类别添加的新方法可以被子类继 ...

  5. Objective-C日记-之类别Category

    类别Category 1,概述 为现有类添加新的方法,这些新方法的Objective-C的术语为“类别”. 2,用法 a,声明类别 @interface NSString(NumberConvenie ...

  6. Objective-C 类别(category)和扩展(Extension)

    1.类别(category) 使用Object-C中的分类,是一种编译时的手段,允许我们通过给一个类添加方法来扩充它(但是通过category不能添加新的实例变量),并且我们不需要访问类中的代码就可以 ...

  7. 分类(类别/Category)与 类扩展(Extension)

    一.分类(类别/Category) 1.适用范围      当你已经封装好了一个类(也可能是系统类.第三方库),不想在改动这个类了,可是随着程序功能的增加需要在类中增加一个方法,这时我们不必修改主类, ...

  8. IOS 类别与扩展的区别 (category & extensions)

    类别 .h @interface NSString(XXXXXX) -(NSInteger)getLen; @end .m @implementation NSString(XXXXXX) -(NSI ...

  9. iOS类别(category)不能添加成员变量但是可以添加属性的问题

    类别不需要介绍了把,网上一大堆(利用Objective-C的动态运行时分配机制,可以为现有的类添加新方法,这种为现有的类添加新方法的方式称为类别catagory,他可以为任何类添加新的方法,包括那些没 ...

随机推荐

  1. springMVC传对象参数、返回JSON格式数据

    假如请求路径:http://localhost/test/test.do?user.id=1 后台接收参数的方法如下: @RequestMapping("/test") publi ...

  2. 无法连接到SQL Server 2008 R2

    服务器环境: 操作系统    名称:    Microsoft Windows Server 2008 R2 Enterprise     版本:    6.1.7601    服务包:    Ser ...

  3. UVa 120 Stacks of Flapjacks【构造法】

    题意:给出n张煎饼,从上到下输入,每张煎饼上面都有一个数字,厨师每次可以选择第k张煎饼,进行翻转操作,设计一种方法使得所有煎饼按照从小到大排序(最上面的煎饼最小) 首先是这个翻转的操作,如下图 如图所 ...

  4. 为什么会出现ADB rejected shell command

    出现这个问题,是由于在运行过程中,android emulator 没有打开,可以在run configurations--target- automatic-设置自己的android-version ...

  5. jrtplib跨网络通讯NAT穿透问题解决方法

    前几篇文章讲了使用jrtplib在Android和pc端进行通讯的方法 在实际项目中,手机端和pc端一般不会在同一个子网内,两者之间联络可能要走路由器之类的NAT(网络地址转换 Network Add ...

  6. MBR与GRUB简介

    在坛子里找到一篇关于grub和mbr工作原理的文章,以前一直都是一头雾水,今天转这文章学习下..哈.. 能正常工作的grub应该包 括一下文件:stage1.stage2.*stage1_5.menu ...

  7. TextView字体和背景图片 设置透明度

    背景图片透明度设置  viewHolder.relative_layout.getBackground().setAlpha(225);     0  ---  225 ((TextView)tv). ...

  8. DataTable转List<Model>通用类【实体转换辅助类】

    /// <summary> /// DataTable转List<Model>通用类[实体转换辅助类] /// </summary> public class Mo ...

  9. ndk文件操作问题及小结

    最近在做文件传输,发现在android下用f系列的C库函数去读取文件文件大小会受到2G大小的约束,查阅了很久,最后只能去看google的libc源码,发现了以下几个问题: 1.bionic的libc是 ...

  10. 转载--详解tomcat配置

    http://www.importnew.com/17124.html  原文链接 几乎所有容器类型的应用都会包含一个名为 server.xml 的文件结构.基本上,其中的每个元数据或者配置都是容器完 ...