iOS中的类目(类别)

一、类目的简单介绍

1.什么是类目(类别)

类别( category )是 Objective-C 语言的新特性,为现有的类添加新方法的方式。比如系统的类,我们看不到他的.m文件,所以没有办法用直接添加方法的方式去实现,用类目就可以实现在没有类的源代码的条件下为类增加新的方法。
通过类目加入的方法会成为原始类的一部分。例如:通过类目想NSString增加方法,编译器会把这些方法加到NSString的定义里;类目里定义的方法可以干任何原始类中方法能干的事,在运行时他们是平等对待的;类目里定义的方法也会被原始类的子类所继承,就跟原始类的其他方法一样。

2.类目的局限性

a、无法添加新的实例变量。
b、若在类目中覆盖现有类的原有方法。这样会引起super消息的断裂,因为类目总的方法具有更高的优先级,因此,一般不要覆盖现有类中的方法

3.类目的声明结构

@interface 要加类目的类名A(类目名B)

//声明类目添加的方法

@end


二、类目的添加方法功能

我们下面举一个为系统的类NSString通过类目添加方法的例子

1.首先建立一个项目,添加一个主页MainViewController类,然后为NSString类添加一个类目类NSString+Category

过程:new file->Source->Objective-C File->next

File Type 可以选取类目延展或者协议 File处填写类目名 

之后就会生成NSString+Category的.h和.m文件,之后就可以为NSString类添加方法了,下面直接上代码来说明

NSString+Category.h中

#import <Foundation/Foundation.h>
//前面是要加方法的类名,后面括号内为类目名,该类目中的方法可被NSString的对象调用
@interface NSString (Category)
-(NSNumber *)lengthASNumber;
@end

NSString+Category.m中

#import "NSString+Category.h"

@implementation NSString (Category)

-(NSNumber *)lengthASNumber
{   //self为调用该方法的对象,自己调用自己的方法
    int length=(int)[self length];
    NSNumber *n=[NSNumber numberWithInt:length];
    return n;
}
@end

MainViewController中导入NSString+Category.h后可直接通过NSString调用-(NSNumber *)lengthASNumber方法,例子

NSString *s1=@"one";
//用类目方法实现,该方法属于NSString
NSNumber *n1=[s1 lengthASNumber];


三、类目的拆分功能

其实类目有一个非常重要的功能,就是实现类的方法的拆分(避免一个类中写入方法太多,代码冗余,还可以将同类的方法写入同一个地方,比较合理),下面通过代码来实现类目的拆分功能

同样建一个项目,有一个主页类MainViewController,另外建立一个自己的类MyClass,并为MyClass建立两个类目MyClass+Category1和MyClass+Category2,这里注意,需要把这两个类目的头文件都删除掉,然后将两个类目的声明放在MyClass.h中,MyClass.h代码如下

#import <Foundation/Foundation.h>

@interface MyClass : NSObject
{
    int va1;
    int va2;
    int va3;
}
-(void)setVa1:(int)ava1;
-(int)va1;
@end

//MyClass +Category1头文件中的内容
@interface MyClass (Category1)
//记得,这里的方法和MyClass自己本身的方法是同一级别的
-(void)setVa2:(int)ava2;//赋值
-(int)va2;//返回
@end

//MyClass +Category2头文件中的内容
@interface MyClass (Category2)
-(void)setVa3:(int)ava3;
-(int)va3;
@end

MyClass+Category1.m和MyClass+Category2.m中的代码如下

//这里有个小细节,将MyClass+Category1.h改为MyClass.h
#import "MyClass.h"

@implementation MyClass (Category1)
-(void)setVa2:(int)ava2
{
    va2=ava2;
}
-(int)va2
{
    return va2;
}
@end
//将MyClass+Category2.h改为MyClass.h
#import "MyClass.h"

@implementation MyClass (Category2)

-(void)setVa3:(int)ava3
{
    va3=ava3;
}
-(int)va3
{
    return va3;
}
@end

然后,在MyClass.m中的代码是这样的

#import "MyClass.h"

@implementation MyClass


-(NSString *)description
{
    return [NSString stringWithFormat:@"%d %d %d",va1,va2,va3];
}

-(void)setVa1:(int)ava1
{
    va1=ava1;
}
-(int)va1
{
    return va1;
}
@end

最后,就可以在MainViewController中直接导入MyClass.h然后调用其本身和其类目中的方法了(注意:两个类目中可以添加不相同类型的方法,实现同种方法放在一起,这里就不再详细实现了)

        MyClass *m=[[MyClass alloc]init];
        [m setVa1:1];
        [m setVa2:2];
        [m setVa3:3];
        
        NSLog(@"%@",m);
至此,类目的介绍基本完成。


四、说说类目与继承的区别

使用类目无需生成子类,可以直接为现有类添加方法,继承则需要生成子类来实现添加方法;子类可以重写父类方法,同时可以继承调用父类的实现,但是类目扩展的方法如果与现有类的方法重名,会覆盖原类的实现,无法访问到原来的方法;子类可以为父类扩展属性和成员变量,这一点类目无法实现。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值