类别和扩展
类别可以让你的方法添加到现有的类甚至是一个你没有来源。类别是一个强大的功能,允许您在不进行子类化的情况下扩展现有类的功能。使用类别,您还可以在多个文件中分发您自己的类的实现。
类扩展类似,但允许在主类块以外的位置为类声明其他必需的 API @interface
。
向类添加方法
您 可以添加方法通过在类别名称下的接口文件中声明它们并在同名的实现文件中定义它们来创建类。类别名称表示这些方法是在其他地方声明的类的添加,而不是新类。但是,您不能使用类别向类添加其他实例变量。
类别添加的方法成为类类型的一部分。例如,添加到NSArray
类中的类的方法包含在编译器期望NSArray
实例在其库中具有的方法中。NSArray
但是,在子类中添加到类中的方法不包含在NSArray
类型中。(这仅适用于静态类型的对象,因为静态类型是编译器知道对象类的唯一方法。)
类别方法可以执行本类中定义的方法可以执行的任何操作。在运行时,没有区别。类添加到类中的方法由所有类的子类继承,就像其他方法一样。
类别接口的声明看起来非常类似于类接口声明 - 除了类名称在类名称后面的括号中列出,并且未提及超类。除非其方法不访问该类的任何实例变量,否则该类别必须为其扩展的类导入接口文件:
#import“ClassName.h”
@interface ClassName(CategoryName)
//方法声明
@end
请注意,类别不能为类声明其他实例变量; 它只包括方法。但是,类范围内的所有实例变量也在范围内该类别。这包括类声明的所有实例变量,甚至是声明的实例变量@private
。
您可以添加到类中的类别数量没有限制,但每个类别名称必须不同,并且每个类别都应声明并定义一组不同的方法。
扩展
类扩展类似于 匿名类别
,除了它们声明的方法必须@implementation
在相应类的主块中实现。使用Clang / LLVM 2.0编译器,您还可以在类扩展中声明属性和实例变量。
类扩展的一个常见用途是重新声明以readwrite形式公开声明为私有的属性:
@interface MyClass:NSObject
@property(retain,readonly)float value;
@end
//私有扩展,通常隐藏在主实现文件中。
@interface MyClass()
@property(retain,readwrite)float value;
@ end
请注意(与类别相反)在第二个@interface
块的括号中没有给出名称。
对于一个类来说,拥有公开声明的API通常也是常见的,然后私有地声明其他方法,仅供类所在的类或框架使用。类扩展允许您在主类块以外的位置为类声明其他必需的方法@interface
,如以下示例所示:
@interface MyClass : NSObject
- (float)value;
@end
@interface MyClass () {
float value;
}
- (void)setValue:(float)newValue;
@end
@implementation MyClass
- (float)value {
return value;
}
- (void)setValue:(float)newValue {
value = newValue;
}
@end
该setValue:
方法的实现必须出现在类的主@implementation
块中(您不能在类别中实现它)。如果不是这种情况,编译器会发出警告,指出它无法找到方法定义setValue:
。
网友评论