Objective-C - KVC如何在引擎盖下工作?

Bla*_*ckM 2 objective-c key-value-observing ios kvc

我正在与KVC合作,我想知道它是如何工作的.

因为它使用键和值,我可以假设self每个对象的每个对象都包含一个字典keys = properties namevalues = setters.因此,当我调用[self setValue:aValue forKey:@"aProperty"]该对象时,从指向setter方法的键获取哈希值.

所有这一切当然都是猜测,以及如何用我的知识实现它.

它是如何在引擎盖下工作的?

mip*_*adi 5

从概念上讲,你是在正确的轨道上,虽然它有点复杂.

首先,请记住Objective-C是一种动态语言.本质上,每个类都维护一个方法名称到它们实际实现的映射(它们只是C函数).这类似于您所谈论的字典,尽管它由Objective-C运行时本身管理.

每次调用方法都会使用此映射.例如,假设你有这段代码:

[obj doSomething];
Run Code Online (Sandbox Code Playgroud)

真正发生的是,在运行时,Objective-C运行时搜索obj名为"doSomething"的条目的方法映射.这将返回运行时调用的函数,obj作为第一个参数传入该函数.

因为方法是在运行时调度的,所以Objective-C提供了许多使用字符串调用函数的方法.(getattr(obj, "doSomething")()如果您熟悉Python,这类似于在Python中执行某些操作.)

Objective-C运行时本身还跟踪实例变量的名称以及它们实际位于内存中相对于对象的位置.

这就是KVC能够做到这一点的方式.你打电话的时候:

[obj setValue:@"value" forKey:@"property"];
Run Code Online (Sandbox Code Playgroud)

KVC运行时使用Objective-C运行时首先查找调用的方法setProperty.运行时取对应于该方法的功能,然后将KVC机械可以调用该方法,通过obj@"value"作为参数,以该函数.

如果找不到方法怎么办?那么,KVC机器使用Objective-C运行时中的函数等来查找具有相同名称的实例变量ivar_getOffset.可能在某些时候它使用类似object_setIvar设置实例变量的函数.(这是猜测,但我认为关于KVC如何与实例变量相比起作用是一个很好的猜测.)

如果KVC无法同时找到方法和实例变量,则调用setValue:forUndefinedKey:或者valueForUndefinedKey:可以选择在类上定义以动态处理属性.


简而言之,您有正确的想法,但属性名称到方法(或ivars)的映射是由Objective-C运行时完成的,并且可能归功于Objective-C的动态特性.


另请注意,KVC的工作原理非常简单.KVO变得有点复杂.