【OC底层】AssociatedObject 关联对象 2019-10-07

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

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

  1> 添加关联对象

  void objc_setAssociatedObject(id object, const void * key,   id value, objc_AssociationPolicy policy)

  2> 获得关联对象

  id objc_getAssociatedObject(id object, const void * key)

  3> 移除所有的关联对象

  void objc_removeAssociatedObjects(id object)

 

key的常见用法

 

objc_AssociationPolicy修饰符

 

 

给分类添加属性实例

假如已经有一个 XGPerson的类,现在我们需要扩展这个类,并且添加一个 age 属性

#import "XGPerson.h"// 分类属性是不会生成 getset 方法的,如果不重写这两个方法,就无法正常使用属性@interface XGPerson (Test)@property (nonatomic,assign) int age;@end

#import "XGPerson+Test.h"#import <objc/runtime.h>@implementation XGPerson (Test)- (void)setAge:(int)age{ // @selector(age) 这个参数只要传一个地址指针就可以 objc_setAssociatedObject(self, @selector(age), @(age), OBJC_ASSOCIATION_ASSIGN);}- (int)age{ // 隐式参数 // _cmd = @selectior(age) return [objc_getAssociatedObject(self, _cmd) intValue];}

调用:

XGPerson* p1 = [[XGPerson alloc]init]; p1.name = @"p1"; p1.age = 18; XGPerson* p2 = [[XGPerson alloc]init]; p2.name = @"p2"; p2.age = 20; NSLog(@"p1Name:%@ p1Age:%i----p2Name:%@ p2Age:%i",p1.name,p1.age,p2.name,p2.age);

输出:

2018-11-29 14:20:38.666084+0800 关联对象(增加分类属性)[1923:87124] p1Name:p1 p1Age:18----p2Name:p2 p2Age:20

 

关联对象的原理

实现关联对象技术的核心对象有

  AssociationsManager  AssociationsHashMap  ObjectAssociationMap  ObjcAssociation

 objc4源码解读:objc-references.mm

   

关联对象存储结构图
    关联对象并不是存储在被关联对象本身内存中关联对象存储在全局的统一的一个AssociationsManager中设置关联对象为nil,就相当于是移除关联对象

 

Copyright © 2019 必富娱乐官网注册 All Rights Reserved
任坚强
地址:栾城县
全国统一热线:15253745684