objective-c
0x01 什么是类别
类别(Category)是objective-c语言的一个特性。
可以在不改变类名和原来类的实现的前提下,实现对类的方法扩展。
0x02 创建类别
类别的声明
类别的声明看起来非常像类的声明,但在类的名称之后是写在括号内的类别名称。
@interface NSString (NumberConvenience)
- (NSNumber *) lengthAsNumber;
@end // NumberConvenience
1、只要保证类别名称唯一,我们可以向一个类中添加任意数量的类别;
2、类别不能添加新的实例变量;
3、类别可以添加属性,而且属性必须是@dynamic类型的。意味着我们可以通过点表达式来访问setter / getter方法。
类别的实现
类别的实现和类的实现非常相似:
@implementation NSString (NumberConvenience)
- (NSNumber *) lengthAsNumber
{
NSUinteger length = [self length];
return ([NSNumber numberWithUnsignedInt:length]);
} // lengthAsNumber
@end // NumberConvenience
类别的优势
在Cocoa中,类别主要有三个用途:
1、类别支持开发人员针对自己构建的类,把相关的方法分组到多个单独的文件中,对于大型而复杂的类,这有助于提高可维护性,并简化单个源文件的管理;
2、创建对私有方法的前向引用。如果编译器发现我们调用对象的某个方法,却没能找到该方法的声明或定义,便会产生警告。只要在类别中声明一个方法,编译器就不会警告了。这就是Cocoa中没有严格意义上的私有方法。但APPle并不允许应用程序访问类中的私有变量和方法,所以这条不展开详述;
3、向对象添加非正式协议(Informal Protocol)。
类别的缺陷
1、无法向现有的类中添加新的实例变量(类别没有空间容纳实例变量);
2、方法名称冲突,即类别中的新方法的名称与现有类中方法名称重名,类别具有更高的优先级。类别中的方法将完全取代现有类中的方法(再也无法访问现有类中的同名方法),可以考虑给类别中的方法加前缀。
0x03 类扩展
类扩展的声明
类别只能增加方法,不能增加实例变量,但使用类扩展(Class Extension)可以做到。
类扩展也叫匿名类别,就是不需要指定类别名字。
功能就是为一个类添加额外的原来没有的变量、方法或者合成属性:
@interface Things ()
{
NSInteger thing4;
}
@property (readwrite, assign) NSInteger thing2;
@property (assign) NSInteger thing3;
@end
类扩展的实现
一般类扩展都是写在.m文件中,不单独建立一个扩展文件,如下:
#import "MyViewcontroller.h"
// 此乃本类的扩展
@interface MyViewController ()
// 在此声明方法,添加成员变量和属性
@end
@implementation MyViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
单独生成一个类扩展文件也可以,但必须将类扩展的.h文件包含进本类的.m文件中。
类扩展的优势
1、能为某个类附加额外的属性,成员变量和方法声明,只是该实例变量默认是@private类型的(作用范围只能在自身类,而不是子类或其他地方);
2、有时我们需要声明一个@property,它对外是只读的(readonly),而对内是可读写的(readwrite),可以通过类扩展实现;
3、一般的私有属性和方法可以写到类扩展。
类扩展的缺陷
1、类扩展中添加的属性、成员变量和方法都属于私有属性和方法(只能被在本类的.m文件调用,并且这些属性和方法不能被子类继承);
2、一般类扩展都是写在.m文件中,不单独建立一个扩展文件,且必须把类扩展的@interface写在本类的@implementation的上方,否则编译器会报错;
3、类扩展只能针对自定义的类,不能给系统类增加类扩展;
4、类扩展定义的方法必须在类的实现中进行实现(因为单独定义类扩展的话编译器只会生成一个.h文件,类扩展只能在需要扩展的类.m文件里面去进行扩展);
5、类扩展中声明的方法可以不实现,但编译器会警告(因为类扩展是在编译阶段被添加到类中,而类别是在运行时添加到类中);
6、单独定义类扩展的文件并且只定义属性,也需要将类实现文件中包含进类扩展文件,否则会找不到属性的setter / getter方法。
0x04 类别和类扩展还有继承的区别
类别 | 类扩展 | 继承 | |
---|---|---|---|
功能 | 为类添加方法,不用知道类的源码,添加变量 | 为类添加私有变量和私有方法,在类的源文件中书写,所以知道类的源代码 | 即能为类添加方法又能添加变量 |
特点 |
添加的方法称为类的一部分,可以被子类继承 |
添加的变量和方法只有这个类内部访问,正常情况下外边不能访问,不能被子类继承 | 新添加的变量和方法只能子类才能具有,父类不具有 |
使用 | 使用原始类的对象(调用-方法)或者类(调用+方法)调用方法 | 在类内部(源文件)使用 | 只能子类使用 |
相关阅读
MSE(Media Source Extensions)的一点尝试
最近对于blob这个东西真的是很感兴趣,图片可以是blob,视频可以是blob,直播也可以是blob,感觉很厉害啊。与之紧密联系的MSE(Media Sourc
Objective-C与C语言的关系 Objective-C是C语言的严格超集,完全兼容C,C语言编写的程序可以不经修改直接被Objective-C编译。 Object
Preference的使用(2) --- PreferenceCategory && Pr
上一节有讲到Preference的基本使用跟API的介绍 ,没有看的话请先阅读 Preference的使用(1)现在介绍其子类PreferenceCategory 跟