正常情况下,分类可以添加方法,但是不能添加属性;
通过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无法直接设置;
网友评论