美文网首页
IOS基础知识-关联对象原理篇

IOS基础知识-关联对象原理篇

作者: 程序员的自我救赎 | 来源:发表于2019-06-26 10:18 被阅读0次

Category能否添加成员变量?如果可以,如何给Category添加成员变量?
答:不能直接添加成员变量,但是可以通过runtime的方式间接实现添加成员变量的效果。虽然在分类中可以写@property添加属性,但是不会自动生成私有属性,也不会生成set,get方法的实现,只会生成set,get的声明,需要我们自己去实现。

方法一:我们可以通过使用静态全局变量给分类添加属性

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

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

方法二:使用RunTime动态添加属性
RunTime提供了动态添加属性和获得属性的方法。

-(void)setName:(NSString *)name
{
    objc_setAssociatedObject(self, @"name",name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSString *)name
{
    return objc_getAssociatedObject(self, @"name");    
}

动态添加属性

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     // 指定相关的对象被复制,原子性   
};

key值只要是一个指针即可,我们可以传入@selector(name)

获得属性

objc_getAssociatedObject(id object, const void *key);

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

移除所有关联对象

- (void)removeAssociatedObjects
{
    // 移除所有关联对象
    objc_removeAssociatedObjects(self);
}

此时已经成功给NSObject添加name属性,并且NSObject对象可以通过点语法为属性赋值。

NSObject *objc = [[NSObject alloc]init];
objc.name = @"xx_cc";
NSLog(@"%@",objc.name);

总结:一个实例对象就对应一个ObjectAssociationMap,而ObjectAssociationMap中存储着多个此实例对象的关联对象的key以及ObjcAssociation,为ObjcAssociation中存储着关联对象的value和policy策略。
由此我们可以知道关联对象并不是放在了原来的对象里面,而是自己维护了一个全局的map用来存放每一个对象及其对应关联属性表格。

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

相关文章

  • IOS基础知识-关联对象原理篇

    Category能否添加成员变量?如果可以,如何给Category添加成员变量?答:不能直接添加成员变量,但是可以...

  • iOS原理篇:关联对象

    前言 Swift中不能再extension中为类添加存储属性,如何利用关联对象变相添加属性呢? 关联对象相关API...

  • iOS关联对象技术原理

    iOS关联对象技术原理 iOS关联对象技术原理

  • iOS原理篇(四):关联对象

    关联对象的使用场合 关联对象的基本使用 关联对象的底层原理 一、关联对象的使用场合默认情况下,因为分类底层结构的限...

  • iOS底层原理总结 - 关联对象实现原理

    iOS底层原理总结 - 关联对象实现原理 iOS底层原理总结 - 关联对象实现原理

  • iOS 基础知识之关联对象

    简介 associatedObject又称关联对象,把一个对象关联到另外一个对象身上,使两者能够产生联系。关联对象...

  • iOS Objective-C 关联对象

    iOS Objective-C 关联对象 1. 关联对象简介 对于关联对象,我们熟悉它的地方就是给分类添加属性。虽...

  • IOS基础知识-OC对象原理篇

    一个NSObject对象占用多少内存? 内存对齐为两个原则:原则 1. 前面的地址必须是后面的地址正数倍,不是就补...

  • iOS对象关联

    什么是关联对象 关联对象是指某个OC对象通过一个唯一的key连接到一个类的实例上。 举个例子:xiaoming是P...

  • iOS:关联对象

    目录一,添加属性二,基本知识三,底层原理四,注意点 一,添加属性 1,在类中添加属性,系统会自动生成带下划线的成员...

网友评论

      本文标题:IOS基础知识-关联对象原理篇

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