类别 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里面,这样的属性或方法其实也是扩展的一种特殊情况啦。。。

上一篇下一篇

猜你喜欢

热点阅读