Runtime给分类添加属性

分类中不能添加属性。

在分类中,@property (nonatomic, assign) NSInteger age;只会生成同名的setter和getter方法,不会生成带_的成员变量和对应的setter和getter方法的实现。

那怎么给分类添加属性呢?使用运行时可以。

oc有两个运行时方法:

添加属性,在setter方法中调用:objc_setAssociatedObject

获取属性,在getter方法中调用:objc_getAssociatedObject

// 本类头文件及实现文件
#import <Foundation/Foundation.h>

@interface Person : NSObject

// 声明一个属性
@property (nonatomic, copy) NSString *name;

@end

#import "Person.h"

@implementation Person
@end
// 分类头文件及实现文件

#import "Person.h"

@interface Person (Extension)

// 分类中声明属性,只会生成setter和getter方法的声明,不会生成带“_”的成员变量和setter和getter方法的实现
@property (nonatomic, assign) NSInteger age;

@end

#import "Person+Extension.h"

// 使用运行时,需要导入头文件
#import <objc/runtime.h>

@implementation Person (Extension)

- (void)setAge:(NSInteger)age{
    // 使用运行时关联对象,person对象(self)强引用age对象,并且设置标记为"age"(可以根据该标记来获取引用的对象age,标记可以为任意字符,只要setter和getter中的标记一致就可以)
    // 参数1:源对象
    // 参数2:关联时用来标记属性的key(因为可能要添加很多属性)
    // 参数3:关联的对象
    // 参数4:关联策略
    objc_setAssociatedObject(self, @"age", @(age), OBJC_ASSOCIATION_RETAIN);
}

- (NSInteger)age{
    // 根据“age”标识取person对象(self)强引用的age对象
    // 参数1:源对象
    // 参数2:关联时用来标记属性的key(因为可能要添加很多属性)
    return [objc_getAssociatedObject(self, @"age") integerValue];
}

@end

调用:

#import "ViewController.h"
#import "Person.h" // 导入本类头文件
#import "Person+Extension.h" // 导入分类头文件

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    Person *per = [[Person alloc] init];
    per.name = @"xiaoming"; // 本类中的属性
    per.age = 22; // 分类中的属性
    NSLog(@"%@--%zd",per.name,per.age); // 本类和分类中的属性都可以打印出来,说明都正常存储了数据    
}

@end
原文地址:https://www.cnblogs.com/panda1024/p/6369036.html