Понять Objective-C время выполнения
Я читал о том, как работает Objective-C, поэтому, пожалуйста, прокомментируйте, если я что-то неправильно понял.
Допустим, у меня есть класс под названием Person. Этот класс может иметь или не иметь метод getSex.
Person *p = [[Person alloc]init];
Здесь память выделяется для экземпляра Person (также создается isa, который указывает на класс Person), init используется для инициализации персоны ivar
[p getSex];
Здесь objc_msgSend(Person,@selector(getSex) вызывается для класса Person. Если класс Person не имеет такого метода, среда выполнения ищет этот метод в корневом классе Person и т. Д. Когда метод найден, вызывается IMP, который является указателем на код блока метода. Затем метод выполняется.
Это верно?
2 ответа
Да, все правильно, за исключением того, что поведение init может инициализировать или не инициализировать все его переменные-члены, так что методы доступа возвращают действительные результаты, хотя разумно предположить, что он инициализирует свойства, если не указано иное.
Есть одна часть, которая немного оторвана.
На самом деле вызов будет одним из этих трех:
objc_msgSend(p, @selector(getSex))
objc_msgSend_fpret(p, @selector(getSex))
objc_msgSend_stret(p, @selector(getSex))
Одно из отличий заключается в том, что первый аргумент относится к объекту, а не к классу.
Кроме того, так как вы не поделились тем, что getSex
метод возвращается, мы не можем знать, будет ли он одним из fpret
/stret
версии или нет. Если метод возвращает значение double (на определенных платформах), fpret
версия будет использоваться. Если метод возвращает значение структуры (на определенных платформах), то stret
версия будет использоваться. Все остальные будут использовать стандартную версию. Все это зависит от платформы во многих отношениях.
Как говорили другие, при выделении будут созданы объекты со всеми переменными экземпляра, установленными в 0
/NULL
и действительный isa
указатель также. Методы инициализации могут или не могут обновлять переменные экземпляра с чем-то значимым.