美文网首页
分类中关联对象实现

分类中关联对象实现

作者: 春风依旧 | 来源:发表于2018-07-07 15:26 被阅读12次

前言:

分类中虽然不能直接添加成员变量,但是我们可以通过间接实现添加成员变量

方法一:使用静态全局变量给分类添加属性

static NSString *_name;
-(void)setName:(NSString *)name
{
    _name = name;
}
-(NSString *)name
{
    return _name;
}

       但是这样_name静态全局变量与类并没有关联,无论对象创建于销毁,只要程序在运行,_name变量就存在,并不是真正意义上的属性。

方法二:使用Runtime动态添加属性

Runtime提供了动态添加属性和获取属性的方法
1、动态添加属性

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

参数一:id object : 给哪个对象添加属性,这里要给自己添加属性,用self。
参数二:void * == id key : 属性名,根据key获取关联对象的属性的值,在objc_getAssociatedObject中通过次key获得属性的值并返回。
参数三:id value : 关联的值,也就是set方法传入的值给属性去保存。
参数四:objc_AssociationPolicy policy : 策略,属性以什么形式保存。

typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
    OBJC_ASSOCIATION_ASSIGN = 0,  // 指定一个弱引用相关联的对象
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, // 指定相关对象的强引用,非原子性
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,  // 指定相关的对象被复制,非原子性
    OBJC_ASSOCIATION_RETAIN = 01401,  // 指定相关对象的强引用,原子性
    OBJC_ASSOCIATION_COPY = 01403     // 指定相关的对象被复制,原子性   
};

2、获得属性

objc_getAssociatedObject(id object, const void *key);
参数一:id object : 获取哪个对象里面的关联的属性。
参数二:void * == id key : 什么属性,与objc_setAssociatedObject中的key相对应,即通过key值取出value。

3、移除所有关联对象

- (void)removeAssociatedObjects
{
    // 移除所有关联对象
    objc_removeAssociatedObjects(self);
}
person2.degree = nil;

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

关联对象的实际运用中的key

static : 代表只能在此文件内访问
1、赋值的key :static void *MyKey = &MyKey;

static void *MyKey = &MyKey;
 // 关联对象
objc_setAssociatedObject(obj, MyKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
 // 获得关联对象
objc_getAssociatedObject(obj, MyKey)

2、内存地址的key : static char MyKey;

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

      const void * _Nonnull key: 仅仅是一个指针,&MyKey地址就可以, static char MyKey;不是一定要用char,这里只是它的字节是一个字节,在此仅仅只传一个指针而已

3、使用属性名作为key : #define JKRevelKey @"revel";
        NSArray *str = @"revel";: 其实@"revel"就是自身的内存地址:唯一性,可以打印 str,内存地址是一样的

objc_setAssociatedObject(obj, @"property", value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_getAssociatedObject(obj, @"property");

4、使用get方法的@selecor作为key
可以使用@selector(getter)来代替_cmd

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

关联对象的原理探索

相关文章

  • 分类中关联对象实现

    前言: 分类中虽然不能直接添加成员变量,但是我们可以通过间接实现添加成员变量 方法一:使用静态全局变量给分类添加属...

  • Objective - C 关联对象(二) 关联对象的底层数据结

    (一)分类 - 关联对象的原理 实现关联对象技术的核心对象有: AssociationsManager Assoc...

  • 关联对象

    在分类中不能添加属性,但是却可以使用 关联对象的方式,给类添加变量。主要重点是: 关联对象的实现方式。 关联对象散...

  • 关联对象

    在分类中不能添加属性,但是却可以使用 关联对象的方式,给类添加变量。主要重点是: 关联对象的实现方式。 关联对象散...

  • 关联对象(给分类添加成员变量)

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

  • OC属性关联的实现原理

    OC中在分类中添加属性用属性关联技术来实现存取值的: 那么系统的属性关联功能是如何实现的呢? 属性关联怎么存储对象...

  • iOS runtime之关联对象AssociatedObject

    在分类中添加属性,使用对象关联来实现: 例子:创建一个label的分类 #import@interfaceUILa...

  • 如何实现分类中添加弱引用属性

    需求: 实现分类中添加弱引用属性 众所周知runtime中关联属性的几种类型如下: 但如果想实现弱引用的关联对象就...

  • 关联对象总结

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

  • iOS-OC基础知识点扩展

    请简述分类实现原理 KVO的实现原理是怎样的 能否为分类添加成员变量 目录 分类 & 关联对象 & 扩展 & 代理...

网友评论

      本文标题:分类中关联对象实现

      本文链接:https://www.haomeiwen.com/subject/ligwuftx.html