Динамическая типизация, Objective-C, как это работает?

#objective-c #dynamic #typing

#objective-c #динамическая #ввод

Вопрос:

Меня интересует, как работает динамическая типизация в Objective-C. Я изучал тип «id», я знаю, что он делает и как его использовать, но мне любопытно… Как такая функциональность реализуется под капотом?

Вы не можете определить / разрешить что-либо во время компиляции, только во время выполнения. Я предполагаю, что это может просто указывать на первый байт какого-либо объекта в памяти, но как хранится сигнатура класса? Как он узнает, на что он в данный момент указывает, и как он реализует различные методы получения для класса указанного объекта?

Ответ №1:

«Под капотом», так сказать, все объекты Objective-C являются структурами C с указателем на объект класса, который представляет их тип. id — это указатель на самую базовую такую структуру, которая выглядит примерно так:

 struct objc_object {
    Class isa;
}
  

id компилятор специально обрабатывает это, поскольку компилятор не выдает вам никаких предупреждений о том, что объект может не реагировать на какой-либо селектор, как это происходит при использовании более строго типизированной переменной.

Когда вы вызываете метод для любого объекта, он следует за этим isa указателем на объект класса и ищет в этом объекте класса функцию реализации для селектора метода, который вы пытались вызвать.

Ответ №2:

Чтобы добавить к ответу Anomie, то, как класс хранит таблицу, на какие сообщения он отвечает, и какие биты кода вызывают эти сообщения, совершенно непрозрачно. Таким образом, в определенной степени никто не может точно ответить, как работает реализация Apple, и она почти наверняка отличается от реализации GNU.

Однако справочник Apple по среде выполнения Objective-C объясняет все, что может выполнять среда выполнения на уровне C. Итак, вы можете увидеть, какие операции возможны для настройки и поиска. По сути, это относительно простая система, состоящая в основном из набора словарей (в неинфлектированном смысле), которые сопоставляют одно с другим, например, из селектора в указатель функции IMP. Если в таблице есть запись для определенного класса, то вызывается соответствующая вещь. Если нет, то проверяются суперклассы, рассматривается стандартный механизм forwardingTargetForSelector: запасной вариант и так далее.

Помимо этого, более конкретные комментарии требуют более конкретных вопросов. Есть много деталей, подобных тому, что наблюдение за значением ключа достигается с помощью метода swizzle (таким образом, среда выполнения настраивает указатель C, который класс будет вызывать для установщика, на тот, который вызывает реальный установщик и информирует того, кто наблюдает), но все это просто конкретные случаи использования среды выполнения, как описано.

Комментарии:

1. Хорошее объяснение, премного благодарен!