类扩展
@interface 类名()
/*属性声明*/
/*方法声明*/
@end
说明:
- 类扩展可以为某一个类添加额外的属性,成员变量,方法等。出现在
.h
声明文件中为公开,出现在.m
实现文件中则表示私有。 - 类扩展一般都是在
.m
文件中,在类实现的上方,比如在我们新建UIController时,系统已经为我们写好了类扩展,再其他文件中,如UIView里,我们也可以手写上述格式来使用类扩展 - 在子类中可以使用父类中
.h
文件中扩展的成员变量和方法,因为他们是公开的,而.m
中的不可以。
分类/类别
@interface 类名(分类名字)
/*方法声明*/
@end
@implementation类名(分类名字)
/*方法实现*/
@end
说明:
- 分类用来为已有的类(可以是系统的类)添加新方法
- 分类一般只扩充方法,不新增属性和成员变量
- 分类添加的方法如果是已存在的(理解为方法重写),那么分类中的方法优先级高于原始类,所影响的范围包括其子类。并且出现以下警告提示。
Category is implementing a method which will also be implemented by its primary class
- 分类中的方法会被继承,子类依然可用。
分类的应用
- 扩展系统类方法
这是我们经常使用分类的情形,分类的好处就是在不新建类的情况下,可以通过扩展系统类方法来实现某种功能,例如分类NSString,将日期转换为字符串类型
@interface NSString(Test)
// 日期转成字符串
+(NSString*)dateToString:(NSDate*)date format:(NSString *)format;
@end
@implementation NSString (Test)
+(NSString*)dateToString:(NSDate*)date format:(NSString *)format{
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:format];
NSString *dateString = [dateFormat stringFromDate:date];
return dateString;
}
@end
这样我们就可以直接通过NSString类来调用日期转字符串方法了:
- 方法工厂
通过分类,我们可以快速完成特定控件初始化。我们通过给UIButton新增方法来说明:
+(UIButton*)buttonNormalWithTitle:(NSString*)title
target:(id)target
selector:(SEL)selector
frame:(CGRect)frame
bgImage:(UIImage*)bgImage
imagePressed:(UIImage*)imagePressed
textColor:(UIColor*)aColor
textFont:(UIFont*)textFont;
- 新增属性
一般来说,分类里是不能添加属性的,即使新增里属性,也不会自动生成setter和getter方法,但是OC的特点之一就是动态运行时,我们可以根据这一特性来关联实现setter和getter方法,以达到新增属性的功能。
这里我们给UIViewController新增属性为例:
@interface UIViewController (Based)
@property (copy ,nonatomic) NSString *name;
@end
#import <objc/runtime.h>
@implementation UIViewController (Based)
-(void)setName:(NSString *)name{
objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
-(NSString *)name{
return objc_getAssociatedObject(self, _cmd);
}
@end
这样你就能在控制器中正常使用属性 name
了。
注:最后一种在分类中添加属性,并不是分类所设计的目的,在非必须的情况,还是少用这种方式来为类添加属性,你可以使用正常的继承方式来添加新的属性。
总结
在 OC 中,分类和扩展有着一定的区别,分类的目前主要是用来为已存在的类添加新的方法的,而扩展通常是为当前类添加私有属性和方法的。分类一般不用于添加属性,即时添加了,编译器也不会为分类中的属性增加对应的成员变量以及setter
和getter
方法的。