iOS设计模式——Category和 Extension

什么是Category

Category模式用于向已经存在的类添加方法从而达到扩展已有类的目的,在很多情形下Category也是比创建子类更优的选择。新添加的方法同样也会被被扩展的类的所有子类自动继承。当知道已有类中某个方法有BUG,但是这个类是以库的形式存在的,我们无法直接修改源代码的时候,Category也可以用于替代这个已有类中某个方法的实体,从而达到修复BUG的目的。然而却没有什么便捷的途径可以去调用已有类中原有的那个被替换掉方法实体了。需要注意的是,当准备有Category来替换某一个方法的时候,一定要保证实现原来方法的所有功能,否则这种替代就是没有意义而且会引起新的BUG。和子类不同的是,Category不能用于向被扩展类添加实例变量。Category通常作为一种组织框架代码的工具来使用。

Category的用途

1.      在不创建继承类的情况下实现对已有类的扩展。

2.      简化类的开发工作(当一个类需要多个程序员协同开发的时候,Category可以将同一个类根据用途分别放在不同的源文件中,从而便于程序员独立开发相应的方法集合)。

3.      将常用的相关的方法分组。

4.      在没有源代码的情况下可以用来修复BUG。

Category的用法

在Obj-C中,声明某一个已有类的Category扩展的方法如下:

[html] view plaincopy

  1. @interface ClassName (CategoryName)  
  2. -methodName1  
  3. -methodName2  
  4. @end  

上面的声明通常是在.h文件中,然后我们在.m文件中实现这些方法:

[html] view plaincopy

  1. @implementation ClassName (CategoryName)  
  2. -methodName1  
  3. -methodName2  
  4. @end  

我们创建一个iOS Single View Applciation名为CategoryExample。然后为创建一个NSString类的category扩展。File->New->File然后选择 Cocoa Touch Objective-C category.命名为ReverseNSString.系统会自动生成一个固定格式ClassName+CategoryName的.h和.m文件。

声明Category

打开NSString+ReverseNSString.h文件,在里面添加如下代码:

[html] view plaincopy

  1. #import <Foundation/Foundation.h>  
  2. @interface NSString (ReverseNSString)  
  3. + (NSString*) reverseString:(NSString*)strSrc;  
  4. @end  

实现Category

NSString+ReverseNSString.m文件中实现reverseString方法:

[html] view plaincopy

  1. #import"NSString+ReverseNSString.h"  
  2. @implementationNSString (ReverseNSString)  
  3. + (NSString*)reverseString:(NSString*)strSrc;  
  4. {  
  5.     NSMutableString *reversedString =[[NSMutableString alloc]init];  
  6.     NSInteger charIndex = [strSrc length];  
  7.     while (charIndex > 0) {  
  8.         charIndex--;  
  9.         NSRange subStrRange =NSMakeRange(charIndex, 1);  
  10.         [reversedString appendString:[strSrcsubstringWithRange:subStrRange]];  
  11.     }  
  12.     return reversedString;  
  13. }  
  14. @end  

剩下的工作就是验证我们的Category了,在view中添加一个按钮ReverseString,并设置相应的action方法为reverseString.在view上再添加一个label,命名为myString,默认值是”HelloCategory Design Pattern!”。点击按钮反转这个字符串。主要代码如下:

[html] view plaincopy

  1. -(IBAction)reverseString:(id)sender {  
  2.     NSString *test = [NSStringreverseString:_myString.text];  
  3. _myString.text = test;     
  4. }  

代码组织

Category用于大型类有效分解。通常一个大型类的方法可以根据某种逻辑或是相关性分解为不同的组,一个类的代码量越大,将这个类分解到不同的文件中就显得越有用,每个文件中分别是这个类的某些相关方法的集合。

当有多个开发者共同完成一个项目时,每个人所承担的是单独的cagegory的开发和维护。这样就版本控制就更加简单了,因为开发人员之间的工作冲突更少了。

Category VS添加子类

并没有什么界限分明的判定标准来作为何时用Category何时用添加子类的方法的指导。但是有以下几个指导性的建议:

  1. 如果需要添加一个新的变量,则需添加子类。
  2. 如果只是添加一个新的方法,用Category是比较好的选择。
  3. 在分类中增加的方法,会被子类所继承,而且在运行时跟其他方法没有区别。
  4. 一般不要在分类中覆盖现有类中的方法。

Category 不添加成员变量

@property 声明的属性只会自动生成get,set方法,并不能生成下划线的成员属性

延展(Extension)

  1. 类的延展就如同时“匿名”的分类,延展中声明的方法在类本身的@implementation和它对应的@end之间实现。
  2. 类又是需要方法只有自己所见,我们可以通过延展的方式定义类的私有方法。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏代码散人

ios开发Runtime详解part3(Method swizzling)

  在 ios开发 Runtime 详解part1和 ios开发 Runtime 详解part2(动态方法解析)中我大致介绍了runtime的基本功能,在这篇文...

11120
来自专栏高性能服务器开发

服务器开发通信协议设计介绍

由于我们的即时通讯软件的用户存在用户状态问题,即用户登录成功以后可以在他的好友列表中看到哪些好友在线,所以客户端和服务器需要保持长连接状态。另外即时通讯软件一般...

25120
来自专栏文渊之博

Hive 时间日期处理总结

最近用hive比较多,虽然效率低,但是由于都是T+1的业务模式。所以也就不要求太多了,够用就行。其中用的吧比较多就是时间了,由于大数据中很多字段都不是标准的时间...

55770
来自专栏数说戏聊

07.时间处理&抽取1.时间处理1.1 字符型转时间型2.时间抽取

6410
来自专栏数据和云

崔华:Oracle 里的哈希连接原理解析

崔华,网名 dbsnake Oracle ACE Director,ACOUG 核心专家 编辑手记:感谢崔华授权我们独家转载其精品文章,也欢迎大家向“Oracl...

37650
来自专栏JavaEdge

Java中的VO,PO等1.2.3.VO(value object) 值对象

428100
来自专栏Vamei实验室

Django ORM模型:想说爱你不容易

作者:Vamei 出处:http://www.cnblogs.com/vamei 严禁转载。

17520
来自专栏菩提树下的杨过

ORM中的继承关系映射全解——单表继承体系、一实体一具体表、一实体一扩展表、接口映射

实体继承是基于OO和关系型数据库软件系统设计中的一个重要主题。本文通过基于NBear的实例解析ORM中的实体继承体系映射的方方面面。 本文涉及的内容包括: 1....

33190
来自专栏个人分享

Spark之SQL解析(源码阅读十)

  如何能更好的运用与监控sparkSQL?或许我们改更深层次的了解它深层次的原理是什么。之前总结的已经写了传统数据库与Spark的sql解析之间的差别。那么我...

15820
来自专栏CSDN技术头条

提高代码可读性的10个技巧

以下为译文: 如果你的代码很容易阅读,这也会帮助你调试自己的程序,让工作变得更容易。 代码可读性是计算机编程领域的一个普遍课题,这也是作为开发人员首先要学习的...

20770

扫码关注云+社区

领取腾讯云代金券