美文网首页
类别 Category 和 类扩展Extension

类别 Category 和 类扩展Extension

作者: Queen_BJ | 来源:发表于2019-12-20 17:55 被阅读0次

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

    相关文章

      网友评论

          本文标题:类别 Category 和 类扩展Extension

          本文链接:https://www.haomeiwen.com/subject/uqgbnctx.html