免费开源的iOS开发学习平台

KVC介绍:3 - 修改readonly属性以及私有属性

KVC和点语法都可以用于对象属性的赋值,但是点语法只能给未被标记为readonly的属性进行赋值,而KVC是更加底层的技术,基本在类的定义中被标注为readonly的属性,也可以使用KVC进行修改,当然一般情况下,我们不建议修改readonly的属性。除此之外,通过runtime遍历出来的私有属性/私有变量也可以通过KVC进行赋值和取值。

为了验证KVC的这个功能,我们在之前创建的Person类中给idNumber属性添加readonly关键字,使其成为一个只读属性。

@interface Person : NSObject
@property(nonatomic,copy,readonly) NSString *idNumber; //只读属性
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int age;
@end

在Person.m中,我们重写init方法,在init方法中给只读属性赋初始值。

- (instancetype)init
{
    self = [super init];
    if (self) {
        _idNumber = @"1234567";
    }
    return self;
}

由于idNumber属性是只读属性,因此我们不能够使用点语法来对其进行修改, 下面的赋值方法编译器会报错。

假如我们一定要修改只读属性,可以使用KVC。如下所示,我们使用setValue:forKey:方法可以对只读属性idNumber的值进行强行修改。

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *person = [[Person alloc] init];
        NSLog(@"修改前:%@",person.idNumber);
        [person setValue:@"7654321" forKey:@"idNumber"];
        NSLog(@"强制修改readonly属性后:%@",person.idNumber);
    }
    return 0;
}

运行结果如下。我们可以看到只读属性的值被强行进行了修改。通常情况下,我们并不推荐这样做,不论是在系统框架中还是第三方框架中,被标注为只读的属性都是不建议程序员进行修改的,强行修改会出现一些不可预知的错误。

示例代码

https://github.com/99ios/5.4.3