美文网首页
Category添加成员变量

Category添加成员变量

作者: 曹来东 | 来源:发表于2018-08-29 16:49 被阅读5次

类中使用@property

@property (nonatomic,strong) NSString * name;
上面代码做了三件事
1.生成成员变量_name
2.生成setter,getter声明
3.生成setter,getter实现

分类Category中使用@property

只会生成setter,getter声明.不会做其他两件事.

不能在Category中直接添加成员变量.

image.png

Category中添加成员变量

@interface LDPerson (Test)
@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) int weight;
@end
#import <objc/runtime.h>

@implementation LDPerson (Test)

- (void)setName:(NSString *)name
{
    objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name
{
    // 隐式参数
    // _cmd == @selector(name)
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setWeight:(int)weight
{
    objc_setAssociatedObject(self, @selector(weight), @(weight), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (int)weight
{
    // _cmd == @selector(weight)
    return [objc_getAssociatedObject(self, _cmd) intValue];
}

字符串常量(字面量写法@"name")存放在常量区,多个字符串常量的地址是相同的.

实现关联对象技术的核心对象

  • AssociationsManager
  • AssociationsHashMap
  • ObjectAssociationMap
  • ObjcAssociation
objc4源码解读:objc-references.mm
class AssociationsManager {
    // associative references: object pointer -> PtrPtrHashMap.
    static AssociationsHashMap *_map;//主要对象
public:
    AssociationsManager()   { AssociationsManagerLock.lock(); }
    ~AssociationsManager()  { AssociationsManagerLock.unlock(); }
    
    AssociationsHashMap &associations() {
        if (_map == NULL)
            _map = new AssociationsHashMap();
        return *_map;
    }
};

class AssociationsHashMap : public unordered_map<disguised_ptr_t, ObjectAssociationMap *, DisguisedPointerHash, DisguisedPointerEqual, AssociationsHashMapAllocator>

class ObjectAssociationMap : public std::map<void *, ObjcAssociation, ObjectPointerLess, ObjectAssociationMapAllocator>

class ObjcAssociation {
        uintptr_t _policy;//主要对象
        id _value;//主要对象
    public:
        ObjcAssociation(uintptr_t policy, id value) : _policy(policy), _value(value) {}
        ObjcAssociation() : _policy(0), _value(nil) {}

        uintptr_t policy() const { return _policy; }
        id value() const { return _value; }
        
        bool hasValue() { return _value != nil; }
    };

实现关联对象的核心代码:
objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
参数解释:
self对象添加关联属性name.隐私策略为OBJC_ASSOCIATION_COPY_NONATOMIC,key@selector(name)即getter
由源码可知:
实现关联对象的核心对象是AssociationsManager,该AssociationsManager内部有一个成员变量AssociationsHashMap
AssociationsHashMap是一个字典数据结构,Keydisguised_ptr_t,key是通过函数DISGUISE(object)获取, object == self.valueObjectAssociationMap.此ObjectAssociationMap中存储着ObjectAssociationMap,ObjectAssociationMap也是一个字典结构,key为我们在API中传入的key即为@selector(name).valueObjectAssociation.在ObjectAssociation中存储这policyvalue
设置关联对象核心API:
void objc_setAssociatedObject(id object,const void * key,id value,objc_AssociationPolicy policy)

  • 关联对象并不是存储在被关联对象本身内存中
  • 关联对象存储在全局统一的一个`AssociationsManager中
  • 设置关联对象为nil就相当于移除关联对象,即属性name的位置传入nil
    关联对象相关API:
    添加关联对象:void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy)
    获得关联对象:id objc_getAssociatedObject(id object, const void * key)
    移除所有的关联对象:void objc_removeAssociatedObjects(id object)

objc_AssociationPolicy

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

相关文章

  • Category能否添加成员变量

    Category能否添加成员变量,如果可以,怎么给Category添加成员变量? 不能直接给Category添加成...

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

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

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

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

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

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

  • OC中的Category添加成员变量

    Category能否添加成员变量? 不能直接给Category添加成员变量,但能间接实现成员变量的效果。能直接添加...

  • 关联对象实现原理

    问题: Category能否添加成员变量?如果可以,如何给Category添加成员变量? 1. 给Category...

  • Category关联对象

    一、分类中添加成员变量Category中添加成员变量.png 所以Category中是不能添加成员变量 二、Cat...

  • Category-关联对象

    分类添加属性 Category能否添加成员变量?如果可以,如何给Category添加成员变量?不能直接给Categ...

  • 关联对象

    O、题:Category能否添加成员变量?如果可以,如何给Category添加成员变量? 答:不能直接给Categ...

  • iOS底层原理 - 关联对象

    面试题引发的思考: Q: Category能否添加成员变量?如果可以,如何给Category添加成员变量? 不能直...

网友评论

      本文标题:Category添加成员变量

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