在实际项目中,用到Category比较多,Category也很实用,我们可以把一些经常用到或者很通用的功能封装到一个Category里,当其他项目需要相同的功能时,我们可以直接拿来用,不用从零开始写,可以提高项目的开发效率。下面我将重点讲解Category:
1.Category是什么?
Category用于向已经存在的类添加方法从而达到扩展已有类的目的,在很多情形下Category也是比创建子类更优的选择,新添加的方法同样也会被被扩展的类的所有子类自动继承。当知道已有类中某个方法有BUG,但是这个类是以库的形式存在的,我们无法直接修改源代码的时候,Category也可以用于替代这个已有类中某个方法的实体,从而达到修复BUG的目的。然而却没有什么便捷的途径可以去调用已有类中原有的那个被替换掉方法实体了。Category通常作为一种组织框架代码的工具来使用。
2.Category的用途
1. 在不创建继承类的情况下实现对已有类的扩展。
2. 简化类的开发工作(当一个类需要多个程序员协同开发的时候,Category可以将同一个类根据用途分别放在不同的源文件中,从而便于程序员独立开发相应的方法集合)。
3. 将常用的相关方法进行分组。
4. 在没有源代码的情况下可以用来修复BUG。
3.Category的用法
创建一个iOS Single View Applciation名为CategoryExample。然后为创建一个NSString类的category扩展。File->New->File然后选择 Cocoa Touch Objective-C category命名为jwl,Category on NSDate,如下图所示:
系统会自动生成一个固定格式NSDate+jwl的.h和.m文件。
声明Category
打开NSDate+jwl文件,在里面添加如下代码:
// // NSDate+jwl.h // JWeiBo // // Created by bcc_cae on 15-9-29. // Copyright (c) 2015年 bcc_cae. All rights reserved. // #import <Foundation/Foundation.h> @interface NSDate (jwl) /** * 判断某个时间是否为今天 */ -(BOOL)isToday; /** * 判断某个时间是否为昨天 */ -(BOOL)isYesterday; /** * 判断某个时间是否为今年 */ -(BOOL)isYear; /** * 将某个时间格式化为yyyy-MM-dd */ -(NSDate *)dateWithYMD; /** * 计算某个时间与当前时间的时间差 */ -(NSDateComponents *)deltaWithNow; @end
实现Category
打开NSDate+jwl.m文件,在里面添加如下代码:
// // NSDate+jwl.m // JWeiBo // // Created by bcc_cae on 15-9-29. // Copyright (c) 2015年 bcc_cae. All rights reserved. // #import "NSDate+jwl.h" @implementation NSDate (jwl) /** * 判断某个时间是否为今天 */ -(BOOL)isToday { NSCalendar *calendar = [NSCalendar currentCalendar]; int unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay; //1.获得当前时间的年月日 NSDateComponents *nowCmps = [calendar components:unit fromDate:[NSDate date]]; //2.获得self的年月日 NSDateComponents *selfCmps = [calendar components:unit fromDate:self]; return nowCmps.year == selfCmps.year && nowCmps.month == selfCmps.month && nowCmps.day == selfCmps.day; } /** * 判断某个时间是否为昨天 */ -(BOOL)isYesterday { NSDate *nowDate = [[NSDate date] dateWithYMD]; NSDate *selfDate = [self dateWithYMD]; //获得nowDate和selfDate的差距 NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *cmps = [calendar components:NSCalendarUnitDay fromDate:selfDate toDate:nowDate options:0]; return cmps.day == 1; } /** * 判断某个时间是否为今年 */ -(BOOL)isYear { NSCalendar *calendar = [NSCalendar currentCalendar]; int unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay; //1.获得当前时间的年月日 NSDateComponents *nowCmps = [calendar components:unit fromDate:[NSDate date]]; //2.获得self的年月日 NSDateComponents *selfCmps = [calendar components:unit fromDate:self]; return nowCmps.year == selfCmps.year; } /** * 计算某个时间与当前时间的时间差 */ -(NSDateComponents *)deltaWithNow { NSCalendar *calendar = [NSCalendar currentCalendar]; int unit = NSCalendarUnitHour | NSCalendarUnitMinute |NSCalendarUnitSecond; return [calendar components:unit fromDate:self toDate:[NSDate date] options:0]; } /** * 将某个时间格式化为yyyy-MM-dd * * @return [fmt dateFromString:str] */ -(NSDate *)dateWithYMD { NSDateFormatter *fmt = [[NSDateFormatter alloc] init]; fmt.dateFormat = @"yyyy-MM-dd"; NSString *str = [fmt stringFromDate:self]; return [fmt dateFromString:str]; } @end</span>
Category能对大型类有效分解。通常一个大型类的方法可以根据某种逻辑或是相关性分解为不同的组,一个类的代码量越大,将这个类分解到不同的文件中就显得越有用,每个文件中分别是这个类的某些相关方法的集合。当有多个开发者共同完成一个项目时,每个人所承担的是单独的cagegory的开发和维护。这样就版本控制就更加简单了,因为开发人员之间的工作冲突更少了。
4.Category和Extension的区别
Category
1).不能向类添加实例变量,只能添加实例方法。
2).名称冲突。类别具有更高优先级,当类别方法名与原始类方法名相同时,类别方法将覆盖原始类方法。
3).Category添加的方法可以不实现。
Extension
1).extentsion可以添加属性。
2).形式上看,Extension是匿名的Category。
3).extension里声明的方法必须实现
5.建议
如果需要添加一个新的变量,则需添加子类。
如果只是添加一个新的方法,用Category是比较好的选择。
感谢 博友的iOS设计模式——Category 文章链接http://blog.csdn.net/lovefqing/article/details/8289851
代码下载地址:http://download.csdn.net/detail/jasonjwl/9238347