zoukankan      html  css  js  c++  java
  • 【OC底层】AssociatedObject 关联对象

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

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

       

    • 关联对象存储结构图

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

    移除对象关联引用源码:

    当一个对象触发 dealloc 时会调用下面的代码:

    可以看出,在调用 dealloc 方法时,不需要我们手动去删除 对象关联信息,它会自己去调用 删除对象关联信息


  • 相关阅读:
    nacos安装配置和部署教程
    springcloudstream整合rabbitmq
    Springboot整合swagger2
    git命令详解
    Mybatis 注解开发传入List 两种方式接收方式 在IN场景中
    java 根据时间段查询数据库
    stream分页
    201521123068《Java程序设计》第1周学习总结
    201521123027 《JAVA程序设计》第二周学习总结
    201521123027 《JAVA程序设计》第一周学习总结
  • 原文地址:https://www.cnblogs.com/xgao/p/10038495.html
Copyright © 2011-2022 走看看