iOS开发:Category的具体使用详解

Category,类别也叫分类,是一种不需要继承就可以给类添加方法的技术,其主要作用就是给已经创建的存在的类添加方法(给系统自带的类扩展方法),而不需要增加一个子类。并且,我们可以在不知道已经创建的某个类内部实现的具体情况下,为该类增加扩展方法。Category和子类不同的是,Category不能用于向被扩展类添加实例变量,所以Category通常可以作为一种框架代码的工具来使用。比如我们想要增加某个框架中的类的方法,Category的使用就非常有用。

一、Category创建步骤:

1、打开项目,然后点击 File -> New -> File,或者用快捷键“commond + n”,新建一个文件,然后选择iOS -> Source -> Objective-C File;

2、打开新建文件弹框之后,在File里面给你新建的Category命名,然后在File Type里面选择“Category”类型,最后在Class里面选择你要扩展那个类的名字,然后Next下一步,最后Create即可完成创建;

这里举个例子,我给我项目里面的AppDelegate类添加一个类别,具体步骤如下:

iOS开发:Category的具体使用详解_第1张图片

iOS开发:Category的具体使用详解_第2张图片

iOS开发:Category的具体使用详解_第3张图片

iOS开发:Category的具体使用详解_第4张图片



二、Category使用:这里还是举一个例子,我在AppDelegate里面写一个关于银联支付的调用方法

iOS开发:Category的具体使用详解_第5张图片

iOS开发:Category的具体使用详解_第6张图片

iOS开发:Category的具体使用详解_第7张图片

iOS开发:Category的具体使用详解_第8张图片

三、Category其他用法

1.调用父类未公开(私有)的方法:

eg:父类CZLabel

.h文件:

#import
@interface CZLabel : UILabel
@end

.m文件:

#import "CZLabel.h"
@implementation CZLabel
- (void)setTextColor {
self.textColor = [UIColor redColor];
}
@end


新建一个CZLabel111继承自CZLabel:

.h文件:

#import "CZLabel.h"
@interface CZLabel111 : CZLabel
@end

.m文件:这里需要在设置text的时候,同时设置文字颜色,调用父类未公开的setTextColor方法

#import "CZLabel111.h"
@implementation CZLabel111
- (void)setText:(NSString *)text {
[super setText:text];
[self setTextColor];
}
@end

如果直接编译会报错:

iOS开发:Category的具体使用详解_第9张图片

错误提示是,找不到父类的方法

所以需要在子类中声明父类的类别之后,再进行编译就可以了:

iOS开发:Category的具体使用详解_第10张图片

类别名private是任意的,但是不可或缺。

注意:苹果官方在审核APP应用上架的时候,会拒绝使用系统私有API的应用,这里只是教会怎么调用私有方法,在实际使用的时候,要慎之又慎,尽量使用其他方法替代这种方法。


2.通过Category实现简单的协议

eg:比如我们需要在文本文字颜色改变的时候,发出一条消息,现在修改CZLabel如下:

CZLabel.h文件:

#import
@interface CZLabel : UILabel
@property(nonatomic) id delegate;
@end
@interface NSObject (CZLabelDelegateMethod)
- (void)textColorChanged:(UIColor *)colorChange;
@end

增加delegate,声明为id,表示可以接受任何类。声明NSObject的类别,声明它实现的方法。

CZLabel.m文件:

#import "CZLabel.h"
@implementation CZLabel
- (void)setTextColor {
self.textColor = [UIColor redColor];
[self.delegate textColorChanged:self.textColor]; //调用代理方法
}
@end


在调用的地方如下:在ViewController.m文件里调用

#import "ViewController.h"
#import "CZLabel111.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
CZLabel111 *label = [[CZLabel111 alloc] initWithFrame:CGRectMake(15, 20, 100, 30)];
label.delegate = self;
label.text = @"iOS软贱攻城狮";
[self.view addSubview:label];
}
- (void)textColorChanged:(UIColor *)colorChange {
NSLog(@"text color changed to %@", colorChange);
}

这个例子就算是利用了任何类都是NSObject子类的特点,通过NSObject的类别实现了一个代理协议。

对比其他正式的协议,这种协议不需要实现类显示声明(eg:),但是这里还有个缺点,当ViewController未实现textColorChanged这个方法,就会崩溃,因此在调用的时候一定要检查代理方法是否实现。解决方法如下:

iOS开发:Category的具体使用详解_第11张图片

四、Category的总结归纳

1️⃣类别的局限性:

1.类别中的方法,会覆盖父类中重名的方法,无法再调用父类中的方法(因为在类别中无法使用super),为了防止意外覆盖,需要每次给类别加上前缀;

2.不同文件中同名类别,同名方法,系统不会报错,系统实际执行的方法会以最后一个加载的文件为准,所以在创建的时候使用前缀会防止类别互相覆盖;

3.类别只能为存在的类添加方法,但不能添加属性(新的实例变量),在类别中声明的属性,无法存取。

2️⃣类别的使用场景

1.可将类别作为一种手段,对头文件中的相关方法声明进行分组,甚至将不同的类别声明放在不同的头文件中,框架在其所有的头文件中使用这些方法技巧可以达到清晰明确的效果,还可使用称为类别扩展的匿名类别,在实现文件(.m文件)中声明专有的属性和专有的方法。

2.Category用于大型的类有效分解。通常一个大型类的方法可以根据某种逻辑或是相关性分解为不同的组,一个类的代码量越大,将这个类分解到不同的文件中就显得越有用,然而每个文件中分别相当于是这个类的某些相关方法的集合。如果需要多个开发人员协同完成同一个项目时,每个人所承担的就是单独的cagegory的开发和维护。这样就使开发人员之间的工作冲突变少。

3️⃣类别和子类的区别

类别和子类的区别没有明确的局限规定,但是可以根据实际开发中的情况来具体情况具体对待,如果需要添加一个新的变量,则就需添加子类;如果只是添加一个新的方法,用Category就比较合适。

4️⃣Category用途

1.扩展已有的类。在不创建继承类的情况下实现对现有类的扩展。
2.引用父类未公开(私有)的方法。
3.实现简单的协议。
4.简化类的开发工作(当一个类需要多个开发人员共同开发的时候,Category可将同一个类根据用途分别放在不同的源文件中,方便开发人员独立开发相应的方法模块)。
5.将常用的相关的方法进行分组处理。
6.在没有源代码的情况下可以用来修复一些问题bug。

你可能感兴趣的:(iOS开发)