Runtime给分类添加属性

本文介绍如何在 Objective-C 的分类中添加属性。通过使用运行时方法 objc_setAssociatedObject 和 objc_getAssociatedObject,可以在不修改原始类的基础上为分类添加属性。

分类中不能添加属性。

在分类中,@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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值