动态添加属性

动态向类中加入属性

(未实现的方法并没有在类的MethodList)
在分类中只能添加方法,不能添加属性,在分类中声明了一个属性,既不自动生成setter和getter方法,也没有成员变量_ivar的生成;所以运用运行时动态添加属性,实际上就是添加了setter和getter方法,但是并没有添加_ivar成员变量
当我们在分类中添加了一个属性

@property (nonatomic, strong) NSString *speed;

当对象调用该属性的时候就是调用起setter方法和getter方法, 我们在setter方法中

- (void)setSpeed:(NSString *)speed {
    objc_setAssociatedObject(self, @selector(speed), speed, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

getter方法

- (NSString *)speed {
   return  objc_getAssociatedObject(self, @selector(speed));
}

如此,就完成了在分类里面动态的添加属性的功能;



既然是运行时添加方法,那是不是可以不在Person分类中添加(破坏了封装性),

//创建一个字典,将属性作为key, 属性值作为value存储在之中
static const NSMutableDictionary *_propDicts;

static const void *  propDict(NSString *propName) {
    if(!_propDicts) _propDicts = [NSMutableDictionary dictionary];
    
    id value = _propDicts[propName];
    if (!value) {
        value = [NSNull null];//当没有该key时,添加进字典
        [_propDicts setValue:value forKey:propName];
    }
    return (__bridge const void *)(value);
}
//setter方法的IMP
static void setPropIMP (id slf, SEL selector, id value ,NSString *propName) {
    objc_setAssociatedObject(slf, propDict(propName), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
//getter方法的IMP
static id getPropIMP(id slf, SEL selector, NSString *propName) {
    return objc_getAssociatedObject(slf, propDict(propName));
}

在viewdidiload方法里为person的属性添加setter方法和getter方法,

 Class cls = NSClassFromString(@"Person");
    //添加setter方法,方法指针指向(IMP)setPropIMP,返回值为void,传有2个隐藏参数@:self, : _cmd 代表该方法, 传入2个参数:@@ key:value
    class_addMethod(cls, @selector(setProp: forKey:), (IMP)setPropIMP, "v@:@@");
    class_addMethod(cls, @selector(getProp:), (IMP)getPropIMP, "@@:@");
    
    Person *p = [Person new];
    [p performSelector: @selector(setProp: forKey:) withObject:@"kcs" withObject:@"name"];
    id name = [p performSelector: @selector(getProp:) withObject:@"name"];
    NSLog(@"%@", name);

你可能感兴趣的:(动态添加属性)