美文网首页Objective-C
iOS:关联对象

iOS:关联对象

作者: 码小菜 | 来源:发表于2019-12-22 11:48 被阅读0次

目录
一,添加属性
二,基本知识
三,底层原理
四,注意点

一,添加属性

1,在类中添加属性,系统会自动生成带下划线的成员变量、get/set方法的声明和实现

@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
- (NSString *)name;
- (void)setName:(NSString *)name;
@end

@implementation Person
- (NSString *)name {
    return _name;
}
- (void)setName:(NSString *)name {
    _name = name;
}
@end

2,在分类中添加属性,系统会自动生成get/set方法的声明,不会生成带下划线的成员变量和get/set方法的实现

@interface Person (Add1)
@property (nonatomic, assign) NSInteger age;
- (NSInteger)age;
- (void)setAge:(NSInteger)age;
@end

@implementation Person (Add1)
@end

3,直接使用分类中的属性会crash,必须手动实现get/set方法

Person *person = [Person new];
person.name = @"111";
person.age = 1; // crash
NSLog(@"%@---%zd", person.name, person.age);

// 打印
-[Person setAge:]: unrecognized selector sent to instance 0x6000022d72b0
二,基本知识

1,介绍

  • 添加关联对象
// 将value与object关联起来,key为关联键值,policy为关联策略
OBJC_EXPORT void
objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key,
                         id _Nullable value, objc_AssociationPolicy policy);
  • 获取关联对象
// 用key从object中取出value
OBJC_EXPORT id _Nullable
objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key);
  • 移除所有关联对象
// 移除与object关联的所有对象
OBJC_EXPORT void
objc_removeAssociatedObjects(id _Nonnull object);

2,策略

objc_AssociationPolicy 修饰符
OBJC_ASSOCIATION_ASSIGN assign
OBJC_ASSOCIATION_RETAIN strong,atomic
OBJC_ASSOCIATION_COPY copy,atomic
OBJC_ASSOCIATION_RETAIN_NONATOMIC strong,nonatomic
OBJC_ASSOCIATION_COPY_NONATOMIC copy,nonatomic

3,使用

@implementation Person (Add1)
- (NSInteger)age {
    return [objc_getAssociatedObject(self, @selector(age)) integerValue];
}
- (void)setAge:(NSInteger)age {
    objc_setAssociatedObject(self, @selector(age), @(age), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
三,底层原理

源码下载地址

1,核心对象

  • AssociationsManager
class AssociationsManager {
    static AssociationsHashMap *_map;
};
  • AssociationsHashMap
class AssociationsHashMap : public unordered_map<disguised_ptr_t, ObjectAssociationMap *>
  • ObjectAssociationMap
class ObjectAssociationMap : public std::map<void *, ObjcAssociation>
  • ObjcAssociation
class ObjcAssociation {
    uintptr_t _policy;
    id _value;
};

2,对象间的关系

  • AssociationsManager(对象):含有一个AssociationsHashMap类型的变量
  • AssociationsHashMap(表):传入的object为key,ObjectAssociationMap为value
  • ObjectAssociationMap(表):传入的key为key,ObjcAssociation为value
  • ObjcAssociation(对象):存储传入的policyvalue
关系图
四,注意点

1, 设置关联对象为nil,就相当于移除该关联对象

objc_setAssociatedObject(self, @selector(age), nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

2,关联对象value并不存储在被关联对象object的内存中,而是存储在全局统一的AssociationsManager

相关文章

  • iOS关联对象技术原理

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

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

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

  • iOS Objective-C 关联对象

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

  • iOS对象关联

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

  • iOS:关联对象

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

  • iOS 关联对象

    在平时的工作中经常碰到给类别添加属性的操作,那么实现思路是怎么样的呢? 代码实现:新建一个Person类和Pers...

  • iOS 关联对象

    可以不改变源码的情况下增加实例变量。可与分类配合使用,为分类增加属性。(类别是不能添加成员变量的(property...

  • iOS 关联对象

    关联对象简单的说就是运用oc语言的运行时特性(runtime),给类别加属性(当然不止加属性).正常的类中创建一个...

  • iOS 关联对象

    在上一篇文章中我们理解了load&&initialize,Category---为什么只能加方法不能加属性[htt...

  • iOS 关联对象

    objc_setAssociatedObject 关联对象使用关联,我们可以不用修改类的定义而为其对象增加存储空间...

网友评论

    本文标题:iOS:关联对象

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