OC底层->关联对象

158 阅读1分钟

类的成员变量

  • 创建一个类,定义一个属性 @property(assign,nonatomic) int XXX;
    • 生成一个成员变量 _XXX
      • {int _xxx}
    • 生成set和get方法的声明
    • 生成set和get方法的实现
  • 分类,定义一个属性
    • 只会做set和get的方法声明
      • -(void)setXXX:(int)XXX;
      • - (int)XXX;

基本用法

#import "MJPerson.h"

@interface MJPerson (Test)
@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) int weight;

@end

#import "MJPerson+Test.h"
#import <objc/runtime.h>

@implementation MJPerson (Test)

- (void)setName:(NSString *)name
{
    objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name
{
    // 隐式参数
    // _cmd == @selector(name)
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setWeight:(int)weight
{
    objc_setAssociatedObject(self, @selector(weight), @(weight), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (int)weight
{
    // _cmd == @selector(weight)
    return [objc_getAssociatedObject(self, _cmd) intValue];
}

@end

思考:如何实现给分类“添加成员变量”?

  • 默认情况下,因为分类底层结构的限制,不能添加成员变量到分类中。但可以通过关联对象来间接实现

  • 关联对象提供了以下API

    • 添加关联对象
      • 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)

key的常见用法

  • static void *MyKey = &MyKey;

    • objc_setAssociatedObject(obj, MyKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    • objc_getAssociatedObject(obj, MyKey)
  • static char MyKey;

    • objc_setAssociatedObject(obj, &MyKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    • objc_getAssociatedObject(obj, &MyKey)
  • 使用属性名作为key

    • objc_setAssociatedObject(obj, @"property", value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    • objc_getAssociatedObject(obj, @"property");
  • 使用get方法的@selecor作为key

    • objc_setAssociatedObject(obj, @selector(getter), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    • objc_getAssociatedObject(obj, @selector(getter))

objc_AssociationPolicy

image.png

关联对象的原理

image.png

image.png