引子
作为ios开发初学者,从书本和博文上看过对于Category的解析,在我的记中,原先对它的理解仅仅是这样的“它叫类目,或者叫类别,作用是能扩充一个类的方法,但不能扩充类的变量!仅此而已。
实际在码代码方面,还没真正用过Category。为加深对Category的理解记忆,实践检验真理,现在不如用代码尝试一下Category究竟是怎么一个东西,如何使用?!
实际在码代码方面,还没真正用过Category。为加深对Category的理解记忆,实践检验真理,现在不如用代码尝试一下Category究竟是怎么一个东西,如何使用?!
代码下载:
点击此处
例子
设题:我们有一个Man类,Man有个Sleep方法,但是我们不满足人只能睡觉,所以我们给它加了一个Fly方法,也就是人能飞起来!
通过使用Category的方法来实现:
1.新建一个Man类
//
// Man.h
// CategoryDemo
//
// Created by fenglh on 14-8-8.
// Copyright (c) 2014年 yons. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Man : NSObject
{
NSString * Name; //名字
}
@property(nonatomic, retain) NSString * Name; //利用property特性类自动完成Name变量的读写访问方法。
- (id) init:(NSString *) MyName; //声明一个初始方法
- (void) Sleep; //声明一个睡觉的实例方法
@end
//
// Man.m
// CategoryDemo
//
// Created by fenglh on 14-8-8.
// Copyright (c) 2014年 yons. All rights reserved.
//
#import "Man.h"
@implementation Man
@synthesize Name;
- (void)Sleep
{
NSLog(@"My Name is %@, I am Sleeping!", Name);
}
//初始话对象实例的时候,也初始化Name
- (id) init:(NSString *) MyName
{
self = [super init];
if(nil != self){
self.Name = MyName;
}
return self;
}
@end
点击Xcode工具的菜单栏:File --> New --File... --> 选择 “Object-C category” --> 点击“next”
在"Category on" 栏我们选在Man类,在“Category”栏写上“SuperMan” ,也就是说,我们要扩充的类是Man类,扩充后类目的名字叫做SuperMan。最后,点击Next完成
在我们的工程中,可以看到编译器给我们添加了两个文件,文件名的命名是有点不一样的!!
3.尝试给SuperMan添加一个变量,看看情况如何?
//
// Man+SuperMan.h
// CategoryDemo
//
// Created by fenglh on 14-8-8.
// Copyright (c) 2014年 yons. All rights reserved.
//
#import "Man.h"
@interface Man (SuperMan)
{
NSString * sex;//尝试添加一个变量
}
@end
你会发现,编译报错。“实例变量不能放置在类目中”!,所以现在可以理解书本上说的,类目不能给原有类添加变量了吧!
4. 扩充类的方法,添加实例方法Fly 以及类方法Run
//
// Man+SuperMan.h
// CategoryDemo
//
// Created by fenglh on 14-8-8.
// Copyright (c) 2014年 yons. All rights reserved.
//
#import "Man.h"
@interface Man (SuperMan)
- (void) Fly; //实例方法
+ (void) Run; //类方法,也就是静态方法
@end
//
// Man+SuperMan.m
// CategoryDemo
//
// Created by fenglh on 14-8-8.
// Copyright (c) 2014年 yons. All rights reserved.
//
#import "Man+SuperMan.h"
@implementation Man (SuperMan)
- (void) Fly
{
NSLog(@"My name is %@, I am flying !", Name);
}
+ (void) Run
{
NSLog(@"I can run !"); //注意:这是类方法也就是静态方法,他不能访问非静态变量“Name”,所以这里不打印名字!
}
@end
5.main方法
//
// main.m
// CategoryDemo
//
// Created by fenglh on 14-8-8.
// Copyright (c) 2014年 yons. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Man.h"
#import "Man+SuperMan.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Man * XiaoMing = [[Man alloc] init:@"XiaoMing"];
[XiaoMing Sleep]; //调用Man类原有的实例方法
[XiaoMing Fly]; //调用通过Category扩充的实例方法
[Man Run]; //调用Category扩充的类方法
}
return 0;
}
6.输出结果
2014-08-08 16:08:52.314 CategoryDemo[838:303] My Name is XiaoMing, I am Sleeping!
2014-08-08 16:08:52.316 CategoryDemo[838:303] My name is XiaoMing, I am flying !
2014-08-08 16:08:52.317 CategoryDemo[838:303] I can run !
小结
1. Category 可以扩充原有类(Man)的方法,不管是实例方法还是类方法!
2.Category 不可以扩充原有类的成员变量,否则编译器会报错!
3.Category 产生的类目(SuperMan)并不是一个类,所以它不能Alloc一个对象,要使用扩充后的方法,仍然需要在被扩充类(Man)上使用!(SuperMan仅仅是个名字并不是产生了一个新的类!)
注:文章如有任何不当之处,请大家多多指教!谢谢!