Я хочу иметь четкое представление о диспетчеризации методов в Swift.Я прочитал из этого популярного блога о трех типах рассылок, как показано ниже:
- Динамический
- Таблица (Таблица свидетелей в Swift)
- Сообщение
В этом блоге автор говорит, что подтипы NSObject поддерживают таблицу диспетчеризации (таблицу свидетелей), а также иерархию диспетчеризации сообщений.Ниже приведен фрагмент кода, представленный автором:
class Person: NSObject {
func sayHi() {
print("Hello")
}
}
func greetings(person: Person) {
person.sayHi()
}
greetings(person: Person()) // prints 'Hello'
class MisunderstoodPerson: Person {}
extension MisunderstoodPerson {
override func sayHi() {
print("No one gets me.")
}
}
greetings(person: MisunderstoodPerson()) // prints 'Hello'
Я приведу аргументацию автора для вызова sayHi () в экземпляре Person :
Метод greetings (person :) использует диспетчеризацию таблиц для вызова sayHi ().Это решает, как и ожидалось, и «Hello» печатается.Здесь нет ничего захватывающего.Теперь давайте создадим подкласс Person
Автор продолжает объяснять вызов sayHi () для экземпляра типа MisunderstoodPerson, передаваемого Person :
Обратите внимание, что sayHi () объявлена в расширении, означающем, что метод будет вызываться при отправке сообщения.Когда вызывается приветствие (person :), sayHi () отправляется объекту Person посредством отправки таблицы.Поскольку переопределение MisunderstoodPerson было добавлено посредством отправки сообщений, в таблице диспетчеризации MisunderstoodPerson по-прежнему имеется реализация Person в таблице диспетчеризации, и возникает путаница.
Я хочу знать, как автор пришел к выводу, что метод greetings (person :) использует диспетчеризацию таблицы для вызова sayHi ()
Одна вещь, о которой автор упоминает ранее в блоге, - это когда подкласс NSObject объявляет метод в первоначальном объявлении (то естьне в расширении) будет использоваться таблица отправки.
Поэтому я предполагаю, что в качестве параметра 'person' типом является Person для greetings (person:) , а вызываемый метод - sayHi (), который объявленв первоначальном объявлении Person class используется отправка таблицы, и sayHi () от Person называется . Можно с уверенностью сказать, что используется таблица свидетелей Person .
Как только мы получим подкласс MisunderstoodPerson и передадим этот экземпляр приветствиям (person :), этот экземпляр следует рассматривать как Человек .У меня тут путаница и у меня есть пара вопросов.
- Экземпляр имеет тип MisunderstoododPerson , поэтому здесь будет использоваться таблица MisunderstoododPerson .
- Или экземпляр был приведен к типу Person , поэтому здесь будет использоваться таблица свидетелей Person .
Автор не разъясняет в блоге, чьи таблицы свидетелей следует использовать,Даже в некоторых случаях мне кажется, что автор описывает даже компиляторы, создающие таблицы свидетелей для протоколов.Это видно из изображения, которое он публикует в блоге, как показано ниже.
Я был бы очень признателен, если бы кто-нибудь мог это объяснить.