【iOS基础】KVC的特殊作用!原来它有Java反射的效果!

今天无意间了解到KVC(Key-Value-Coding)(且并没有了解到KVO(Key-Value-Observe)的情况下),看了半天不知道它的作用何在,通过间接访问属性的方法,这不多此一举么?而且通过 Key 来访问,很容易打错字啊!

因为会 Java 反射的缘故,发觉 KVC 其实还蛮像的,然后我突发奇想,Java 反射能够不通过 set 方法更改属性值,那KVC呢?

当然,它也可以,那么一个对象的属性值为 readonly 时,它也能改变该属性值么?如果能,那它意义就重大了!

下面我就做个实验来验证看看!

首先简单介绍一下先。
KVC,即是指 NSKeyValueCoding,一个非正式的 Protocol,提供一种机制来间接访问对象的属性。而不是通过调用Setter、Getter方法访问。KVO 就是基于 KVC 实现的关键技术之一。

KVC的常用方法:

//根据key读取对象的属性值
- (id)valueForKey:(NSString *)key; 

//设置某个key(属性)的值为value
- (void)setValue:(id)value forKey:(NSString *)key;

很简单的两个方法,一个相当于 getter,一个相当于 setter。

注意:
(1). key的值必须正确,如果拼写错误,会出现异常

(2). 当key的值是没有定义的,valueForUndefinedKey:这个方法会被调用,如果你自己写了这个方法,key的值出错就会调用到这里来

(3). 因为类key反复嵌套,所以有个keyPath的概念,keyPath就是用.号来把一个一个key链接起来,这样就可以根据这个路径访问下去

(4). NSArray/NSSet等都支持KVC

好,基础普及到这里。下面实验开始!

1.新建一个普通的工程。
2.新建一个类,取名为 TestKVC,类里面声明一个属性 name,注意该属性是只读的(readonly)。

#import <Foundation/Foundation.h>

@interface TestKVC : NSObject

@property(nonatomic, readonly) NSString *name;

@end

3.在.m文件里面的初始化定义该属性。

#import "TestKVC.h"

@implementation TestKVC

- (instancetype)init
{
    self = [super init];
    if (self) {
        _name = @"APP"; //初始化名称为“APP”,记住咯!
    }
    return self;
}
@end

4.测试 KVC 是否能够改变该值。(我在 ViewController 的 viewDidLoad 方法里面写的如下代码)

    TestKVC *test = [[TestKVC alloc] init];
    NSLog(@"name is %@", test.name);

    [test setValue:@"AZZ" forKey:@"name"];
    NSLog(@"new name is %@", test.name);

5.有图有真相
【iOS基础】KVC的特殊作用!原来它有Java反射的效果!_第1张图片
看到最下面的打印没有?name 已经被我改成“AZZ”了!

6.直接更改该属性试试(结果当然是不行!~)
这里写图片描述

so,实验成功!

总结:即使属性被设置为了 readonly ,通过 KVC 还是可以更改该属性的值!

如果你有任何问题,欢迎留言告诉我!~

你可能感兴趣的:(ios,反射,效果,作用,KVC)