Runtime为分类添加属性-2021-02-24-周三

2021-02-24  本文已影响0人  勇往直前888

正常情况下,分类可以添加方法,但是不能添加属性;
通过runtime的关联对象,可以实现分类添加属性的目的;

分类头文件添加属性

#import "Person.h"
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface Person (AddProperty)

// 身高,基本数据类型
@property (nonatomic, assign) NSInteger height;

// 职业,字符串,对象类型
@property (nonatomic, copy) NSString *career;

// 位置,结构体
@property (nonatomic, assign) CGPoint location;

@end

NS_ASSUME_NONNULL_END

在实现文件中重写setter/getter

#import "Person+AddProperty.h"
#import <objc/runtime.h>

// 关联对象key
static NSString *heightKey = @"height";
static NSString *careerKey = @"career";
static NSString *locationKey = @"location";

@implementation Person (AddProperty)

#pragma mark - setter/getter
// 身高
- (void)setHeight:(NSInteger)height {
    objc_setAssociatedObject(self, &heightKey, @(height), OBJC_ASSOCIATION_ASSIGN);
}

- (NSInteger)height {
    NSNumber *heightValue = objc_getAssociatedObject(self, &heightKey);
    return [heightValue integerValue];
}

// 职业
- (void)setCareer:(NSString *)career {
    objc_setAssociatedObject(self, &careerKey, career, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)career {
    return objc_getAssociatedObject(self, &careerKey);
}

// 位置
- (void)setLocation:(CGPoint)location {
    NSValue *locationValue = [NSValue valueWithCGPoint:location];
    objc_setAssociatedObject(self, &locationKey, locationValue, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (CGPoint)location {
    NSValue *locationValue = objc_getAssociatedObject(self, &locationKey);
    return [locationValue CGPointValue];
}

@end

测试一下

#import "Person+AddProperty.h"

// 其他内容

// 分类添加属性
- (IBAction)categoryButtonTouched:(id)sender {
    // 设置原有的公共属性
    self.person.name = @"小明同学";
    self.person.age = 41;
    
    // 设置通过分类添加的属性
    self.person.height = 188;
    self.person.career = @"iOS架构师";
    self.person.location = CGPointMake(1280, 30);
    NSLog(@"%@", self.person);
}
2021-02-24 16:50:39.367416+0800 RuntimeDemo[9785:729869] <Person: 0x60000347dce0> {
  height = 188;
  career = iOS架构师;
  location = NSPoint: {1280, 30};
  nickname = nil;
  name = 小明同学;
  age = 41;
}

分类添加的属性和普通的属性一模一样;
私有属性nickname无法直接设置;

参考文章

iOS 分类添加属性

Demo地址

RuntimeDemo

上一篇下一篇

猜你喜欢

热点阅读