iOS 分类和扩展

2022-06-21  本文已影响0人  Hahn_z

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

上一篇下一篇

猜你喜欢

热点阅读