Objective-C - Как KVC работает под капотом?

Я работаю с KVC, и мне интересно, как это работает под капотом.

Поскольку он использует ключи и значения, я могу предположить, что self каждого объекта содержит словарь с keys = properties name а также values = setters, Поэтому, когда я звоню [self setValue:aValue forKey:@"aProperty"] объект получает хеш-значение от ключа, который указывает на метод установки.

Все это, конечно, спекуляция и то, как я реализовал бы это со своими знаниями.

Так работает под капотом?

1 ответ

Решение

Концептуально вы на правильном пути, хотя это немного сложнее.

Прежде всего, имейте в виду, что Objective-C - это динамический язык. По сути, каждый класс поддерживает сопоставление имен методов с их фактическими реализациями (которые являются просто функциями C). Это похоже на словарь, о котором вы говорите, хотя он управляется самой средой выполнения Objective-C.

Это отображение используется каждый раз, когда вызывается метод. Например, допустим, у вас есть этот бит кода:

[obj doSomething];

Что действительно происходит, так это то, что во время выполнения Objective-C выполняет поиск objотображение метода для записи с именем "doSomething". Это возвращает функцию, которую затем вызывает среда выполнения, передавая obj в качестве первого параметра этой функции.

Поскольку методы отправляются во время выполнения, Objective-C предоставляет несколько способов вызова функций с использованием строк. (Это сродни делать что-то вроде getattr(obj, "doSomething")() в Python, если вы знакомы с Python.)

Сама среда выполнения Objective C также отслеживает имена переменных экземпляра и их местонахождение в памяти относительно объекта.

Вот как KVC может делать свое дело. Когда вы звоните:

[obj setValue:@"value" forKey:@"property"];

Среда выполнения 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 довольно прост в работе. КВО становится немного сложнее.

Другие вопросы по тегам