使用 RunTime 给分类添加属性

通常在分类中只能声明方法,不能添加属性变量,但是其实可以通过关联对象(Objective-C Associated Objects)实现给分类添加属性的。

首先,给分类添加属性不会自动生成getter、setter方法,需要使用关联对象Runtime提供的这几个接口来实现。

//添加关联对象
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
//获取关联的对象
id objc_getAssociatedObject(id object, const void *key)
//移除关联的对象
void objc_removeAssociatedObjects(id object)
  • 参数解释
id object:被关联的对象
const void *key:关联的key,要求唯一
id value:关联的对象
objc_AssociationPolicy policy:内存管理的策略
  • 内存管理的策略
typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
    OBJC_ASSOCIATION_ASSIGN = 0,           /**< Specifies a weak reference to the associated object. */
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object. 
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   /**< Specifies that the associated object is copied. 
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_RETAIN = 01401,       /**< Specifies a strong reference to the associated object.
                                            *   The association is made atomically. */
    OBJC_ASSOCIATION_COPY = 01403          /**< Specifies that the associated object is copied.
                                            *   The association is made atomically. */
};
内存策略 属性修饰 描述
OBJC_ASSOCIATION_ASSIGN @property (assign) 或 @property (unsafe_unretained) 指定一个关联对象的弱引用。
OBJC_ASSOCIATION_RETAIN_NONATOMIC @property (nonatomic, strong) 指定一个关联对象的强引用,不能被原子化使用。
OBJC_ASSOCIATION_COPY_NONATOMIC @property (nonatomic, copy) 指定一个关联对象的copy引用,不能被原子化使用。
OBJC_ASSOCIATION_RETAIN @property (atomic, strong) 指定一个关联对象的强引用,能被原子化使用。
OBJC_ASSOCIATION_COPY @property (atomic, copy) 指定一个关联对象的copy引用,能被原子化使用。

接下来,给UIView添加一个Color分类,并使用关联对象RunTime给UIView添加一个属性foregroundColor。

  • 创建分类,在.h文件中添加属性。
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface UIView (Color)

@property (nonatomic, strong) UIColor *foregroundColor;

@end

NS_ASSUME_NONNULL_END
  • 在.m文件中引入runtime头文件,需要添加一个关联对象时的用来标记对应的那个属性的key,为了保证这个key唯一不变,使用静态变量,有三种写法,效果是一样的。
//静态变量存储地址唯一不变
static NSString *kForegroundColorKey = @"kForegroundColorKey";
static void *kForegroundColorKey = &kForegroundColorKey;
static char kForegroundColorKey;
  • 添加属性的getter、setter方法
#import "UIView+Color.h"
#import "objc/runtime.h"

@implementation UIView (Color)

static char kForegroundColorKey;

- (void)setForegroundColor:(UIColor *)foregroundColor{
    objc_setAssociatedObject(self, &kForegroundColorKey, foregroundColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UIColor *)foregroundColor {
    return objc_getAssociatedObject(self, &kForegroundColorKey);
}

@end
  • 使用
UIView * view = [[UIView alloc]init];
view.foregroundColor = [UIColor whiteColor];
UIColor * color = view.foregroundColor;
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容