Ответ
Message Dispatch. Метод ищут в runtime Objective-C по селектору. У класса для этого есть свой список, в каждой записи селектор и адрес нужного метода. Runtime идет по списку класса, потом по списку родителя, пока не найдет селектор. Нашли селектор, из этой же записи берут адрес метода и вызывают его.
Селектор это уникальное имя метода в runtime. Грубо говоря, это не строка с именем, а его номер. Одинаковые имена получают один номер. Сравнить два селектора значит проверить, что номер совпал.
Достоинства:
- Реализацию можно менять во время выполнения. Например, method swizzling: у селектора в списке класса подменяют адрес тела метода.
- На этом стоят KVO, Target-Action и вызов по
#selector. - После первого поиска селектор кэшируют. Следующий вызов с тем же именем уже не обходит весь список методов.
Недостатки:
- Самый медленный вид диспетчеризации. Даже с кэшем это тяжелее прямого вызова и virtual table.
- Нужен runtime Objective-C. Для метода Swift это
@objc dynamicу наследникаNSObject.
Так работают:
- Методы с
@objc dynamicу наследниковNSObject. Даже вызов из Swift идет по селектору. - Target-Action. Например, кнопка вызывает метод по
#selector. - KVO у свойств
@objc dynamic. Можно подписаться на изменение свойства, runtime сам вызовет код, когда значение поменяется.