美文网首页
iOS 分类和扩展

iOS 分类和扩展

作者: Hahn_z | 来源:发表于2022-06-21 11:50 被阅读0次

    iOS 分类和扩展

    分类 Category

    分类(Category)是OC中的特有语法,它是表示一个指向分类的结构体的指针。原则上它只能增加方法,不能增加成员(实例)变量。

    分类 Category 属性和成员变量

    在分类中可以写@property, 但是不会生成setter/getter方法,也不会实现成员变量。如果强制使用会报错。
    不过可以通过runtime的关联对象的方法在Category使用成员变量

    新建PersonModel文件

    // PersonModel.h
    @interface PersonModel : NSObject
    
    @property (assign, nonatomic) int age;
    
    @end
    
    // PersonModel.m
    #import "PersonModel.h"
    
    @implementation PersonModel
    
    @end
    

    为PersonModel创建Category

    // PersonModel+Category.h
    @interface PersonModel (Category)
    
    @property (copy, nonatomic) NSString *name;
    @property (copy, nonatomic) NSString *objName;
    @end
    
    // PersonModel+Category.m
    #import "PersonModel+Category.h"
    #import <objc/runtime.h>
    
    static NSString *objNameKey = @"objNameKey";
    @implementation PersonModel (Category)
    
    - (void)setObjName:(NSString *)objName
    {
        objc_setAssociatedObject(self, &objNameKey, objName, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    
    - (NSString *)objName
    {
        return objc_getAssociatedObject(self, &objNameKey);
    }
    
    @end
    

    使用

        PersonModel *person = [PersonModel new];
        person.age = 10;
        NSLog(@"person age = %d",person.age);
        
        // 复值失败,因为Category只是添加了属性,没有添加成员变量
    //    person.name = @"jack";
    //    NSLog(@"person name = %@",person.name);
        
        person.objName = @"jack";
        NSLog(@"person objName = %@",person.objName);
    

    返回

    person age = 10
    person objName = jack
    

    分类 Category 同名方法执行顺序

    同名方法执行顺序为 分类 > 本类 > 父类
    如果多个分类和本类有同名的方法,调用该方法的时候执行由编译器决定。

    在RootController

    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        NSLog(@"name = %@",self);
    }
    

    为RootController创建Category

    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        NSLog(@"Category name = %@",self);
    }
    

    返回

    Category name = <RootController: 0x12df0ec90>
    

    扩展

    Extension:扩展, 延展, 匿名分类;放在.m文件中。一般用于声明私有属性(不对子类暴露)、声明私有方法、声明私有成员变量。

    创建PersonModel的Extension - PersonModel+Ex

    @interface PersonModel ()
    
    @property (copy, nonatomic) NSString *exStr;
    
    - (void)exDemo;
    
    @end
    

    在PersonModel.m里处理exStr和exDemo

    - (void)exDemo
    {
        PersonModel *model = [PersonModel new];
        model.exStr = @"Ex";
        NSLog(@"ex = %@",model.exStr);
    }
    

    分类和扩展的区别

    分类(Category) 扩展(Extension)
    运行时决议 编译时决议
    有单独的.h和.m文件 以声明的方式存在,寄生于宿主类的.m文件
    可以为系统类添加分类 不能为系统类添加扩展
    看不到源码的类可以添加分类 没有.m源码的类无法为其添加扩展

    Github地址

    懒得打的可以直接打开项目查看
    Github地址 https://github.com/HahnLoving/iOS_Study

    相关文章

      网友评论

          本文标题:iOS 分类和扩展

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