Objc 委托Category 的基本理解

引子


作为ios开发初学者,从书本和博文上看过对于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


2.添加一个Category
点击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仅仅是个名字并不是产生了一个新的类!)


注:文章如有任何不当之处,请大家多多指教!谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值