类别 Category 和 类扩展Extension
2019-12-20 本文已影响0人
Queen_BJ
一、类别 Category
作用:给系统类添加方法
背景
在大型项目,企业级开发中多人同时维护同一个类,此时程序员A因为某项需求只想给当前类currentClass添加一个方法newMethod,那该怎么办呢? 最简单粗暴的方式是把newMethod添加到currentClass中,然后直接实现该方法就OK了。 但考虑到OC是单继承的,子类可以拥有父类的方法和属性。 如果把newMethod写到currentClass中,那么currentClass的子类也会拥有newMethod。但真正的需求是只需要currentClass拥有newMethod,而currentClass的子类不会拥有。 苹果为了解决这个问题,就引入了分类(Category)的概念。
如果想添加属性,可以通过runtime手动添加setter/getter方法
代码如下
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSString (Judge)
@property (copy, nonatomic) NSString *name;
-(void)judgeEmpty;
+ (void)testClass;
@end
NS_ASSUME_NONNULL_END
#import "NSString+Judge.h"
#import <objc/runtime.h>
// 定义key
static const void * externVariableKey = &externVariableKey;
@implementation NSString (Judge)
-(void)judgeEmpty
{
[NSString testClass];
NSLog(@"实例方法");
}
+ (void)testClass
{
NSLog(@"类方法");
}
- (void)setName:(NSString *)name
{
objc_setAssociatedObject(self, &externVariableKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
-(NSString *)name
{
return objc_getAssociatedObject(self, &externVariableKey);
}
@end
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 调用类方法
[NSString testClass];
// 调用实例方法
NSString *str = [[NSString alloc]init];
[str judgeEmpty];
str.name = @"张三";
}
@end
二、类扩展Extension
Extension是Category的一个特例,类扩展与分类相比只少了分类的名称,所以称之为“匿名分类”
Extension能为某个类附加额外的属性,成员变量,方法声明
一般的类扩展写到.m文件中
一般的私有属性写到类扩展
创建类扩展只有 .h 文件 没有.m文件
其实可以理解成原有类多了一个.h文件,但写在这个头文件里面的属性、方法等,都是私有的,只能被这个类所拥有访问。
其实这情况大家经常写的,
就是 .m文件里的定义属性,有时我们不会在.h里写属性,因为那样会变成public,只要import后,外部都可以访问。
如果我们只想当前类用一下,只需要写在.m里面,这样的属性或方法其实也是扩展的一种特殊情况啦。。。