Category添加成员变量

类中使用@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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容