category and extension

1.类别

很多时候你会发现你想为一个已经存在的类增加方法,并且希望这个方法适用于该类的所有子类,这时候你应该会用到category。

category用于向已有的类增加方法,你甚至不需要知道该类的实现代码

类别一般是生命在一个单独的头文件中并且在一个单独的代码文件中实现,比如下面的例子,尽管通过category添加的方法适用于对应类的所有实例以及他的子类,在你需要使用这些额外方法的时候你也需要引用category的头文件,不然你会收到编译警告和错误。下面是一个实现category的例子:

#import "XYZPerson.h"
 
@interface XYZPerson (XYZPersonNameDisplayAdditions)
- (NSString *)lastNameFirstNameString;
@end

#import "XYZPerson+XYZPersonNameDisplayAdditions.h"
 
@implementation XYZPerson (XYZPersonNameDisplayAdditions)
- (NSString *)lastNameFirstNameString {
    return [NSString stringWithFormat:@"%@, %@", self.lastName, self.firstName];
}
@end

你除了可以使用类别向已知的类增加方法外,你还可以使用类别将一个复杂的类的实现放到多个文件中。比如NSWindow,改类的文档在打印时将超过60页。如果将NSWindow类的所有代码组织在一个文件中,即使是Cocoa得开发团队也会觉得其过于庞大而难以驾驭,这时候他会将一些相关方法的实现放到一个类别中。查看文档我们可以看到

@interface NSWindow : NSResponder
然后是一大堆类别,其中包括下面这些
@interface NSWindow(NSKeyboardUI)
@interface NSWindow(NSToolbarSupport)

在类别中包含一个属性声明是合法的语法,但是在类别中声明额外的实例变量是不可能的。也就是说编译器不会自动生成任何实例变量,也不会生成任何属性访问方法,你可以在类别视线中写你自己的实现方法,但是你不可能获取属性的变量,除非该属性本来就是类别所扩充类的属性。下面举例说明

@interface ZZFViewController (test)
@property (nonatomic, strong) NSString      *test;
@end
上面这种写法是没有问题,但是编译器没有自动生成_test实例变量,它实际上是为ZZFViewController声明了两个方法。

- (void)setTest:(NSString *)test

- (NSString *)test
如果想为类增加属性就需要用到下面将要介绍的类扩展。


注意:由于类别中方法的优先级比较高,如果在类别中想类新增的方法名和该类自身就有的方法名相同,那么类别中的方法会把原有方法给覆盖掉。还有一点就是对于同一个类的不同类别,如果增加了相同名称的方法,也会给执行造成困扰,所以给类增加方法的时候一定要注意方法的命名。


2.扩展

类扩展和类别有点相似,但是类扩展只能在你已经有源代码的时候才可以使用。通过扩展增加的方法在类的 @implementation   中实现,所以如果你没有源码的话是无法使用扩展的,比如你不能为NSString增加一个扩展
声明一个类扩展的额语法和声明类别的方法差不多,如下:
@interface ClassName ()
 
@end
因为花括号里面没有名字,所有有的时候扩展也被称为匿名类别。

Unlike regular categories, a class extension can add its own properties and instance variables to a class. If you declare a property in a class extension, like this:

和一般的类别不同,一个类的扩展可以为其增加属性和实例变量。如果你像下面这样声明属性
@interface XYZPerson ()
@property NSObject *extraProperty;
@end
你还可以使用类扩展隐藏一些私有信息,比如你可以讲一个属性在头文件中声明为只读,但是在类扩展中将其设置为可读写的,这样该属性对于外边来说是只读的,但对他自己是可读写的。如下:
@interface XYZPerson : NSObject
...
@property (readonly) NSString *uniqueIdentifier;
- (void)assignUniqueIdentifier;
@end

@interface XYZPerson ()
@property (readwrite) NSString *uniqueIdentifier;
@end
 
@implementation XYZPerson
...
@end

你可能感兴趣的:(category and extension)