Category添加成员变量

2018-08-29  本文已影响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")存放在常量区,多个字符串常量的地址是相同的.

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

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)

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
上一篇 下一篇

猜你喜欢

热点阅读