IOS面试题——OC之KVC原理(6)

一 面试题汇总

  1. 什么是KVC,常见的API有哪些
  2. setValue:forKey:方法查找顺序是什么样的
  3. valueForKey:方法的查找顺序是什么样的
  4. accessInstanceVariablesDirectly方法有什么作用

二 面试题解答(仅供参考)

2.1 什么是KVC,常见的API有哪些

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

KVC(Key-Value Coding)是 Cocoa 中的一种机制,它允许开发者通过键(Key)来访问对象的属性值,而不是通过显式的方法调用。通过 KVC,可以在运行时动态地访问和修改对象的属性,而无需显式地调用对象的 getter 和 setter 方法。

常见的 KVC API 包括:

1-valueForKey::
1.1-这个方法用于获取对象指定键(Key)对应的属性值。
如果对象有相应的 getter 方法,该方法会直接调用 getter 方法获取属性值;
如果对象没有相应的 getter 方法,该方法会直接访问对象的实例变量。
1.2-这个方法还可以用于访问对象的集合属性,例如获取数组中每个对象的某个属性值。

2-setValue:forKey::
2.1-这个方法用于设置对象指定键(Key)对应的属性值。
如果对象有相应的 setter 方法,该方法会直接调用 setter 方法设置属性值;
如果对象没有相应的 setter 方法,该方法会直接修改对象的实例变量。
2.2-这个方法也可以用于修改对象的集合属性,例如修改数组中每个对象的某个属性值。

3-valueForKeyPath::
3.1-这个方法用于获取对象指定键路径(Key Path)对应的属性值。
键路径是由多个键(Key)按照点号(.)连接而成的路径,用于访问对象的嵌套属性。
3.2-该方法会递归地沿着键路径访问对象的属性,直到找到最终的属性值为止。

4-setValue:forKeyPath::
4.1-这个方法用于设置对象指定键路径(Key Path)对应的属性值。
与 setValue:forKey: 类似,但可以设置对象的嵌套属性。

5-mutableArrayValueForKey::
这个方法用于获取对象指定键对应的可变数组,该数组是一个特殊的代理数组,
可以直接修改对象的集合属性,而不需要调用对象的 setter 方法。

通过使用这些 KVC API,开发者可以实现更加灵活和通用的对象操作,
从而简化代码逻辑,提高代码的可读性和可维护性。

2.2 setValue:forKey:方法查找顺序是什么样的

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
在调用 setValue:forKey: 方法时,系统会按照以下顺序查找属性的设置方式:

1-调用自动生成的 setter 方法:

1.1-首先,系统会尝试调用对象的自动生成的 setter 方法来设置属性值。
如果对象有一个以属性名开头,后面跟着大写字母的方法,
且参数类型与属性类型匹配的方法,那么系统会调用这个方法来设置属性值。
1.2-例如,如果对象有一个名为 setName: 的方法,并且属性的名称是 name,
那么系统会首先尝试调用 setName: 方法来设置属性值。

2-直接访问实例变量:

2.1-如果对象没有对应的 setter 方法,系统会尝试直接访问对象的实例变量来设置属性值。
它会查找名称为 _propertyName 或者 propertyName 的实例变量,并直接赋值给该变量。
2.2-如果存在 _propertyName 实例变量,则系统会直接将属性值赋给该实例变量。
2.3-如果不存在 _propertyName 实例变量,但存在 propertyName 实例变量,则系统会直接将属性值赋给该实例变量。

3-触发 KVC 通知:
3.1-如果上述两种方式都没有找到合适的设置属性值的方式,
系统会触发 KVC(Key-Value Coding)通知,查找是否有适当的 KVC 方法来设置属性值。
3.2-如果对象实现了 setValue:forKey: 或者 set<Key>: 方法,系统会调用这些方法来设置属性值。

总的来说,setValue:forKey: 方法会按照自动生成的 setter 方法、直接访问实例变量、
触发 KVC 通知的顺序查找属性的设置方式。
如果在这些步骤中找到了适当的设置属性值的方式,系统就会使用该方式来设置属性值。

2.3 valueForKey:方法的查找顺序是什么样的

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

当调用 valueForKey: 方法时,系统会按照以下顺序查找属性的值:

1-调用自动生成的 getter 方法:

1.1-首先,系统会尝试调用对象的自动生成的 getter 方法来获取属性的值。
如果对象有一个以属性名开头,后面跟着大写字母的方法,
且返回类型与属性类型匹配的方法,那么系统会调用这个方法来获取属性的值。
1.2-例如,如果对象有一个名为 name 的属性,并且有一个名为 name 的方法,
那么系统会首先尝试调用 name 方法来获取属性的值。

2-直接访问实例变量:

2.1-如果对象没有对应的 getter 方法,系统会尝试直接访问对象的实例变量来获取属性的值。
它会查找名称为 _propertyName 或者 propertyName 的实例变量,并直接返回该变量的值。
2.2-如果存在 _propertyName 实例变量,则系统会直接返回该实例变量的值。
2.3-如果不存在 _propertyName 实例变量,但存在 propertyName 实例变量,则系统会直接返回该实例变量的值。

3-触发 KVC 通知:

3.1-如果上述两种方式都没有找到合适的获取属性值的方式,
系统会触发 KVC(Key-Value Coding)通知,查找是否有适当的 KVC 方法来获取属性的值。
3.2-如果对象实现了 valueForKey: 或者 <key> 方法,系统会调用这些方法来获取属性的值。

总的来说,valueForKey: 方法会按照自动生成的 getter 方法、直接访问实例变量、
触发 KVC 通知的顺序查找属性的值。如果在这些步骤中找到了属性的值,系统就会返回该值

2.4 accessInstanceVariablesDirectly方法有什么作用

1
2
accessInstanceVariablesDirectly 是一个用于控制 KVC(Key-Value Coding)行为的布尔属性,
它定义在 NSObject 类中。该属性指示 KVC 在访问对象属性时是否直接访问实例变量

三 参考

  • 简书—OC之KVC原理