美文网首页
iOS Category的问题

iOS Category的问题

作者: chaeyeonyanse | 来源:发表于2018-09-04 15:07 被阅读0次

    Category一般称为分类,扩展,主要是为一些无法知道源码的类比如系统类,添加一些功能方法
    可以添加的有,实例方法,类方法

    category不可以添加属性的原因
    分类本身不是一个类,其本质是在运行时,将定义的方法添加到原类的方法列表中的
    成员变量这个概念是相对于类存在的,既然分类不是一个类,那它就不能添加成员变量(实例变量),从而也不能添加属性
    因为添加一个属性,其实是做了三件事

    @property (nonatomic, assign) int age;
    

    1、生成了同名的,以_开头的成员变量: _age
    2、定义了getter和setter,并且在.m文件中实现了这两个方法
    3、在实现代码部分(.m 文件),实现了这两个方法

    - (int)age;
    - (void)setAge:(int)age;
    

    在分类中添加一个属性,其实只是定义了getter和setter方法,没有实现这两个方法,也没能生成同名的以_开头的成员变量

    image.png image.png

    访问该属性时崩溃

    -[Person age]: unrecognized selector sent to instance 0x7fd50af0f410
    

    可以在.m文件中定义这两个方法,在外部访问age时不会再崩溃

    - (int)age {
        return _age;
    }
    - (void)setAge:(int)age {
        _age = age;
     }
    

    但是在里面访问_age会报错

    image.png

    那如何实现呢,这就涉及到了使用runtime提供的两个关联对象的方法了

    objc_getAssociatedObject(...)
    objc_setAssociatedObject(...)
    
    static const char * ageKey = "AgeKey";
    static const char * nameKey = "NameKey";
    - (int)age {
        return [objc_getAssociatedObject(self, ageKey) intValue];
    }
    - (void)setAge:(int)age {
        objc_setAssociatedObject(self, ageKey, @(age), OBJC_ASSOCIATION_ASSIGN);
    }
    - (NSString *)name {
        return objc_getAssociatedObject(self, nameKey);
    }
    - (void)setName:(NSString *)name {
        objc_setAssociatedObject(self, nameKey, name, OBJC_ASSOCIATION_COPY);
    }
    

    这样可以达到正常使用这个属性的目的,但是仍然没有生成_age这个成员变量

    Person *p = [Person new];
    p.age = 20;
    p.name = @"张三";
    NSLog(@"age = %d, name = %@",p.age, p.name);
    //console 打印:age = 20, name = 张三
    

    相关文章

      网友评论

          本文标题:iOS Category的问题

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