类别(Category)
类别和分类是一个概念,它是OC中特有的语法,它是一个指向分类的结构体的指针。原则上来说类别是用来给本类扩充方法的,是不可以添加属性和成员变量的。
类别的格式如下(Device是本类名称,括号中的Aditional是分类的名称):
// .h文件
#import "Device.h"
@interface Device (Aditional)
@end
// .m文件
#import "Device+Aditional.h"
@implementation Device (Aditional)
@end
分类的特点如下:
- 分类结构体指针中只有方法列表,没有属性列表,所以原则上分类只能添加方法,不能添加属性和成员变量。实际上可以通过runtime来添加属性(其实就是通过runtime添加setter/getter方法,不能添加成员变量)。
- 分类中可以写
@property
,但是不会生成setter/getter方法和成员变量,在一些特殊的场合可以自己实现setter/getter方法,否则的话直接运行会因为找不到setter/getter方法而报错。 - 分类中可以访问本类.h中的属性。
- 如果分类中有和本类中同名的方法,那么最终会执行分类中的方法;如果多个分类中都有和本类同名的方法,那么最终会执行最后一个参与编译的分类中的方法,也就是说这是由编译器决定的。
- 子类是可以访问父类的分类的方法的。
- 分类中添加发方法没有实现的话会报警告。分类中添加的方法一般是在分类的
@implementation
实现,但是如果在编译时如果在分类的@implementation
中没有找到方法的实现部分,编译器会向上去本类查找,如果本类也没有那就继续向上去本类的父类查找,所以只要在查找链中有一个地方实现了分类的方法就可以正常运行,否则程序就会崩溃。
类扩展(Extension)
类扩展也叫匿名分类,因为类扩展的格式和分类很现实,只是分类的括号里面是分类名字,而类扩展的括号中是空的,所以叫匿名分类。
其实在实际开发中类扩展使用很频繁。常用的就是在.m文件的@implementation
前面添加类扩展部分,其作用是给类添加额外的方法、属性和成员变量。
类扩展格式如下:
#import "Device.h"
@interface Device ()
@property (nonatomic , strong) NSString *deviceName;
// 类扩展中声明的方法要在本类的implementation中实现,否则会报警告
- (void)testFunction;
@end
@implementation Device
- (void)testFunction{
}
@end
类扩展的特点如下:
- 类扩展不但可以添加方法,也可以添加属性和成员变量。
- 类扩展添加的成员变量默认是
@private
的。 - 类扩展中添加的方法没有实现的话也会报警告。
- 类扩展不像分类那样拥有独立的
@implementation
部分,所以类扩展添加的方法的实现要在本类的@implementation
中来实现。 - 一般类扩展是写在.m文件中,此时类扩展中的方法是私有的。但类扩展也是可以写在.h文件中的,此时类扩展中的方法是公有的。
- 当调用类扩展中添加的方法时,会首先在当前类中去查找该方法的实现,如果当前类中没有实现就会去其父类查找,直到找到该方法的实现未知,如果一直找到基类都没有找到这个方法的实现就会报错。
网友评论