- 类别的作用
- 将类的实现分散到多个不同文件或多个不同框架中:相当于文件瘦身(把类似作用的方法整理一块)方便代码管理
- 创建对私有方法的前向引用:如果其他类中的方法未实现,在你访问其他类的私有方法时编译器报错这时使用类别,在类别中声明这些方法(不必提供方法实现),编译器就不会再产生警告
- 向对象添加非正式协议:创建一个NSObject的类别称为 “创建一个非正式协议”,因为可以作为任何类的委托对象使用(当类别所在类和引用该类别的类同时实现一个方法时优先调用类别类的实现方法)
- 类别使用场景
- 类包含了很多个方法实现,而这些方法需要不同团队的成员来实现
- 当你在使用基础类库中的类时,你不想继承这些类而只想添加一些方法时。
- 调用其他类的私有方法
- 当非正式协议使用
- 举例说明
#import "ClassName.h"
@interface ClassName ( CategoryName )
// method declarations
@end
- 类别添加自定义属性
当向类别中添加自定义属性时会报instance variables may not be placed in categories错误
@interface LMReadingVC (Helper)<UIToolbarDelegate>
{
NSString *topbar;/*报错instance variables may not be placed in categories */
}
正确添加方法
@interface NSObject (XY)
@property (nonatomic, strong) id tempObject;
@end
@implementation NSObject (XY)
@dynamic tempObject;
- (id)tempObject
- {
id object = objc_getAssociatedObject(self,NSObject_key_tempObject);
return object;
}
- (void)setTempObject:(id)tempObject
{
[self willChangeValueForKey:@"tempObject"];
objc_setAssociatedObject(self, NSObject_key_tempObject, tempObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self didChangeValueForKey:@"tempObject"];
}
@end
Extension简要说明
Extension非常像是没有命名的类别。
@interface MyClass : NSObject
@property (retain, readonly) float value;
@end
//一般的时候,Extension都是放在.m文件中@implementation的上方。
@interface MyClass ()
@property (retain, readwrite) float value;
@end
使用Extension需要注意的点:
(1) Extension中的方法必须在@implementation中实现,否则编译会报错。
偷懒引用网友例子说明创建对私有方法的前向引用
/*********person.h***********/
#import <Foundation/Foundation.h>
@interface person : NSObject
+ (void)getAge;
@end
/*********person.m***********/
#import "person.h"
@interface person ()
+ (void)getName;
@end
@implementation person
+ (void)getAge {
NSLog(@"age:18");
}
+ (void)getName {
NSLog(@"name:XXX");
}
@end
然后正常情况下别的类想要直接调用getName是调用不了的,会报错
然后我又创建了一个Category,在.h里声明方法getName,.m什么也没写
#import "person.h"
@interface person (TEXT)
+ (void)getName;
@end
然后在要调用的类import这个Category,再去运行上图的代码,就不会报错,而且getName的私有方法也执行了