美文网首页
动态添加属性

动态添加属性

作者: 么么木木 | 来源:发表于2017-02-14 16:32 被阅读23次

    动态向类中加入属性

    (未实现的方法并没有在类的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);
    

    相关文章

      网友评论

          本文标题:动态添加属性

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