Category
Category的出现,主要是为没有源代码(只有声明)的类添加方法。比如oc提供的类,都是只有.h声明部分,没有.m实现部分。此时我们可以通过category来向某个类添加我们想要实现的功能,加入的这些代码方法,将会加入到那个类中,成为该类的一部分,并且如果该类被继承,这个category的代码也会被继承。
注意一下几点:
1、category中不能添加实例变量,与Extension有区别。
2、category中能添加方法。
3、如果category中我们定义的方法,与该类中某个方法重名,会重写该方法,并且只会执行category中得方法,不会去执行类内的同名方法。所以我们在写category时,应避免这样的重名方法发生,这就需要我们在方法前加上一些识别前缀,一般用名字首字母和下划线作为前缀。
创建category
command+N,在面板中,选中OS X--->sourse—>Objective-c file,next,File Type选择 category,class选择我们要再哪个类中添加category,File写上我们的功能名字。
新建出来的category的文件名为类名+功能名.h和.m一对文件。
与普通类一样,在.h文件中声明方法(注意不能添加实例变量),在.m中写方法实现。注意方法要加前缀。
NSString+sayHi.h
#import <Foundation/Foundation.h>
@interface NSString (SayHi)//category,不是一个类,是NSString的一个类目 //category中不能添加实例变量 //category能添加方法 //类目中方法的优先级,比本类的要高,如果重名,如果重名,优先调用类目中的方法。 //所以,写类目的方法一定要加前缀 + (void)dh_sayWhat; + (void)sayWhat;
- (void)dh_sayHi; - (void)sayHi; //重写便利构造器 + (instancetype)dh_string; + (instancetype)string; //重写实例方法 - (NSString *)dh_substringFromIndex:(NSUInteger)from; - (NSString *)substringFromIndex:(NSUInteger)from; @end |
NSString+sayHi.m文件
#import "NSString+SayHi.h"
@implementation NSString (SayHi) - (void)sayHi{ NSLog(@"想留不能留才最寂寞.."); } + (void)sayWhat{ NSLog(@"hello what"); } //重写便利构造器 + (instancetype)string{ NSLog(@"重写便利构造器.."); return nil; } //重写实例方法 - (NSString *)substringFromIndex:(NSUInteger)from{ NSLog(@"实例:真的是我么?"); return nil; }
@end |
main.m
#import <Foundation/Foundation.h> #import "NSString+SayHi.h" int main(int argc, const char * argv[]) { @autoreleasepool { //2015年04月21日11:23:17 北京 NSString *str = [NSString string ]; [str sayHi];//实例方法 [NSString sayWhat];//类方法
[NSString string ];//2015-04-21 11:42:38.945 OCLesson7_Category[1402:60572] 重写便利构造器.. NSString *str = [[NSString alloc]init]; [str substringFromIndex:1];//2015-04-21 11:46:14.511 OCLesson7_Category[1423:61799] 实例:真的是我么? } return 0; } |
上面的例子,有的重写了NSString类的方法,在main中执行的时候,执行的是我们category中定义的方法。所以在此强调,写category方法一定要加上前缀。
一个例子:
写类方法,实现字符串转换成NSDate
NSDate+StringToDate.h
#import <Foundation/Foundation.h> @interface NSDate (StringToDate) + (NSDate*)ls_dateWithDateString:(NSString *)aString; @end |
NSDate+StringToDate.m
#import "NSDate+StringToDate.h"
@implementation NSDate (StringToDate)
+ (NSDate*)ls_dateWithDateString:(NSString *)aString{
NSDateFormatter *nsf = [[NSDateFormatter alloc]init]; [nsf setDateFormat:@"yyyyMMddHHmmss"]; NSDate *date = [nsf dateFromString:aString]; NSTimeZone *zone = [[NSTimeZone alloc]init]; NSInteger offset = [zone secondsFromGMT];
return [date dateByAddingTimeInterval:offset]; } @end |
main.m
#import <Foundation/Foundation.h> #import "NSDate+StringToDate.h" int main(int argc, const char * argv[]) { NSDate *date = [NSDate ls_dateWithDateString:@"20140402142850"]; NSLog(@"%@",date); } return 0; } |