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