首页 iOS开发:KVC
文章
取消

iOS开发:KVC

KVC(Key-Value Coding)是一种机制,通过该机制可以使用字符串来访问对象的属性和成员变量。iOS开发中,KVC是一个很常用的技术,在实际开发中也有很多应用场景。

KVC的原理

KVC的原理很简单,就是利用字符串来动态地访问一个对象的属性和成员变量。在Objective-C中,每个类都有一个方法叫做setValue:forKey:,这个方法可以接收一个任意类型的对象和一个字符串作为参数。当我们调用这个方法时,系统会根据传入的字符串来查找对象的属性或成员变量,并将传入的值设置给它。

举个例子,如果我们有一个Person类,其中包含一个名为name的成员变量,那么我们可以通过以下代码来设置它的值:

1
2
Person *p = [[Person alloc] init];
[p setValue:@"张三" forKey:@"name"];

KVC的优势

使用KVC的好处主要有以下几点:

  1. 动态访问属性或成员变量

使用KVC可以动态地访问一个对象的属性或成员变量,不需要在代码中直接写出属性或成员变量的名称,从而提高了代码的灵活性和可维护性。

  1. 对象与字典之间的转换

在实际开发中,我们经常需要将一个对象转换为字典,或者将一个字典转换为对象。这时候,使用KVC可以非常方便地实现这个功能。我们可以利用setValue:forKey:方法将一个对象的属性值设置为字典中对应的值,也可以利用valueForKey:方法将一个字典中的值取出来并赋给对象的属性。

  1. 远程配置

有些应用程序需要在运行时从服务器获取配置信息,此时我们可以使用KVC来完成这个功能。例如,我们可以将服务器返回的JSON数据解析成字典,然后通过KVC将字典中的值设置为对象的属性。

KVC的使用

设置属性值

使用KVC设置属性值非常简单,只需要调用对象的setValue:forKey:方法,传入要设置的值和属性名称即可。例如:

1
2
Person *p = [[Person alloc] init];
[p setValue:@"张三" forKey:@"name"];

注意,被设置的属性必须是可写的,否则会导致运行时错误。

获取属性值

使用KVC获取属性值也非常简单,只需要调用对象的valueForKey:方法,传入属性名称即可。例如:

1
NSString *name = [p valueForKey:@"name"];

同样地,被获取的属性必须是可读的,否则会导致运行时错误。

访问私有成员变量

有些情况下,我们需要访问对象的私有成员变量,而这些成员变量通常是不可访问的。使用KVC可以轻松地实现这个功能,只需要将成员变量的名称以“_”开头即可。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//KVC实现
@interface MyClass : NSObject

@property (nonatomic, strong) NSString *publicProperty;

@end

@implementation MyClass {
    NSString *_privateProperty;
}

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

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 创建对象
        MyClass *obj = [[MyClass alloc] init];
        
        // 访问私有成员变量
        [obj setValue:@"newValue" forKey:@"_privateProperty"];
        NSLog(@"%@", [obj valueForKey:@"_privateProperty"]);
    }
    return 0;
}

//runtime实现
Ivar ivar = class_getInstanceVariable([self class\], "_privateProperty");
id value = object_getIvar(self, ivar);

字典转模型

在实际开发中,我们经常需要将服务器返回的JSON数据解析成模型对象。这个过程可以通过KVC来实现,其步骤如下:

  1. 将JSON数据解析成字典;
  2. 创建模型对象;
  3. 遍历字典中的键值对,将值设置为模型对象的属性值。

代码示例:

1
2
3
4
5
6
7
NSDictionary *jsonData = ...; // 服务器返回的JSON数据
Person *p = [[Person alloc] init]; // 创建模型对象

for (NSString *key in jsonData) {
    id value = [jsonData objectForKey:key];
    [p setValue:value forKey:key];
}

注意,这个过程中,字典中的键值对必须与模型对象的属性名称一一对应。

模型转字典

有时候,我们需要将一个模型对象转换成字典,以便于上传到服务器或者存储到本地。这时候,我们可以利用KVC来实现这个功能。代码示例:

1
NSDictionary *dict = [p dictionaryWithValuesForKeys:@[@"name", @"age", @"gender"]];

这里使用了NSDictionary类的dictionaryWithValuesForKeys:方法,它会返回一个字典,该字典包含指定的键所对应的值。

应用举例

使用KVC验证表单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (NSDictionary *)validateFormWithInputs:(NSArray<NSDictionary<NSString *, NSString *> *> *)inputs {
    NSMutableDictionary *validatedInputs = [NSMutableDictionary dictionary];
    
    for (NSDictionary<NSString *, NSString *> *input in inputs) {
        NSString *propertyName = input.allKeys.firstObject;
        NSString *propertyValue = input.allValues.firstObject;
        
        if ([self valueForKey:propertyName] == nil || [propertyValue isEqualToString:@""]) {
            return nil;
        }
        
        validatedInputs[propertyName] = propertyValue;
    }
    
    return validatedInputs;
}
本文由作者按照 CC BY 4.0 进行授权