• 注册
  • iOS博客 iOS博客 关注:0 内容:64

    iOS 关联对象 (objc_setAssociatedObject/objc_getAssociatedObject)

  • 查看作者
  • 打赏作者
  • 当前位置: 职业司 > iOS开发 > iOS博客 > 正文
    • iOS博客
    • category分类中 @property 并不会自动生成实例变量以及存取方法,所以一般使用关联对象为已经存在的类添加 “属性”。使用 objc_getAssociatedObject 以及 objc_setAssociatedObject 来模拟属性的存取方法

      在category使用关联对象前首先需要导入<objc/runtime.h>的头文件

      #import <objc/runtime.h>
      复制代码
      OC中提供的关联对象api
      关联对象set方法
      objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key,  id _Nullable value, objc_AssociationPolicy policy)
      关联对象get方法
      objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key)
      移除关联的对象
      objc_removeAssociatedObjects(id _Nonnull object)
      复制代码
      参数意义
      • object 被关联的对象 也就是对象的主分支
      • key key值 , key与关联的对象是一一对应关系。必须全局唯一。通常使用方式有@selector(methodName) 关联方法对象 或 使用&自定义KEY (__bridge const void *)(自定义KEY )绑定自定义静态KEY值
      • value 要关联的对象或值
      • policy 关联策略

      objc_AssociationPolicy policy 有五种关联策略,视同nonatomicstrong 等修饰符

      /**
      * Policies related to associative references.
      * These are options to objc_setAssociatedObject()
      */
      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_AssociationPolicy policy 等同的修饰符
      OBJC_ASSOCIATION_ASSIGN @property(weak)
      OBJC_ASSOCIATION_RETAIN_NONATOMIC @property(strong, nonatomic)
      OBJC_ASSOCIATION_COPY_NONATOMIC @property(copy, nonatomic)
      OBJC_ASSOCIATION_RETAIN @property(strong,atomic)
      OBJC_ASSOCIATION_COPY @property(copy, atomic)

      示例代码

      #import <objc/runtime.h>
      @implementation UITextField (LengthLimit)
      static NSString *kLimitTextLengthKey = @"kLimitTextLengthKey";
      - (void)setMaxLength:(int)length {
      objc_setAssociatedObject(self, (__bridge const void *)(kLimitTextLengthKey), [NSNumber numberWithInt:length], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
      [self addTarget:self action:@selector(textFieldMaxLengthLimit:) forControlEvents:UIControlEventEditingChanged];
      }
      - (void)textFieldMaxLengthLimit:(id)textField {
      NSNumber *lengthNumber = objc_getAssociatedObject(self, (__bridge const void *)(kLimitTextLengthKey));
      int maxLength = [lengthNumber intValue];
      }
      复制代码

      _cmd 相关

      _cmd 在Objective-C的方法中表示当前方法的selector,正如同self表示当前方法调用的对象实例。

      cmd的作用域只在当前方法里,直指当前方法名@selector

      #import "NSObject+AssociatedObject.h"
      #import <objc/runtime.h>
      @implementation NSObject (AssociatedObject)
      - (void)setAssociatedObject:(id)associatedObject {
      objc_setAssociatedObject(self, @selector(associatedObject), associatedObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
      }
      - (id)associatedObject {
      return objc_getAssociatedObject(self, @selector(associatedObject));
      }
      这里使用_cmd替换如下方式  二者是同意义
      - (id)associatedObject {
      return objc_getAssociatedObject(self, _cmd);
      }
      @end
      复制代码

      请登录之后再进行评论

      登录

      手机阅读天地(APP)

      • 微信公众号
      • 微信小程序
      • 安卓APP
      手机浏览,惊喜多多
      匿名树洞,说我想说!
      问答悬赏,VIP可见!
      密码可见,回复可见!
      即时聊天、群聊互动!
      宠物孵化,赠送礼物!
      动态像框,专属头衔!
      挑战/抽奖,金币送不停!
      赶紧体会下,不会让你失望!
    • 实时动态
    • 签到
    • 做任务
    • 发表内容
    • 偏好设置
    • 到底部
    • 帖子间隔 侧栏位置:
    • 还没有账号?点这里立即注册