Как на самом деле работает делегирование iOS?
Я понимаю, как использовать делегирование с уже существующими объектами iOS. Например, если я создаю экземпляр UITableView, и мой контроллер представления соответствует делегату UITableView, я могу реализовать различные методы делегата UITableView. Моя вновь созданная таблица может получать уведомления, например, когда вызывается didSelectRowAtIndexPath.
Мой вопрос: почему мой стол получил этот конкретный обратный вызов делегата? Насколько я понимаю, делегат - это просто список методов без реализации. Мне кажется, должно быть что-то еще. Что на самом деле происходит "за кадром"?
Изображение, если бы я переименовал все методы делегата в следующее: - mysteryMethod1 - mysteryMethod2 - mysteryMethod3... и т. Д. Один из этих методов отвечает за установку высоты строки для определенного индекса. Еще один из этих методов будет отвечать за редактирование определенной строки.
Все, что я прочитал о делегировании, говорит, что делегат заключает с делегатом договор. Делегат обещает реализовать методы. Когда это происходит, все как-то правильно подключено, и все волшебным образом работает. Какова магия, которую я не вижу?
1 ответ
Я думаю, что для того, чтобы узнать, как на самом деле работают делегаты, вы должны сначала создать свой собственный пользовательский делегат, чтобы вы увидели, что под капотом нет магии, вы, вероятно, не сможете увидеть реализацию фактической сборки Apple в методах делегатов. но я вас уверяю, что в них реализовано много логики, но она не доступна по соображениям конфиденциальности, я полагаю. Когда вы создаете свой собственный делегат, скажем, например...
У вас есть класс А, и в этом классе вы начинаете с создания протокола
protocol ClassADelegate: class {
func changeBackgroundColor(_ color: UIColor?)
}
В этом классе у вас есть свойство делегата, подобное этому.
weak var delegate: ClassADelegate?
Допустим, этот класс является Viewcontroller, и у вас есть IBACtion на нем, как UIbutton, и ваша цель состоит в том, чтобы при нажатии этой кнопки другой ViewController в вашем приложении изменил свой цвет фона на синий. Внутри этого действия в классе А вы делаете это...
func someAction() {
delegate?.changeBackgroundColor(.blue)
}
Допустим, что "магия" происходит здесь, в классе A, кстати, если вы думаете, что делегаты, использующие UITableview, считают, что UItableView - это класс A.
Хорошо, теперь у вас есть класс B, где вы хотите изменить цвет правильно? Что ж, теперь класс B должен соответствовать такому протоколу, как вы также соответствуете протоколу UITableViewDelegate и т. Д.
class ClassB: UIViewController, ClassADelegate {
}
Теперь подумайте над словом делегат на секунду и подумайте, что это значит, вы просто делегируете ответственность кому-то другому, верно? и да, в этом случае ClassB будет делегирован, для этого нам нужно иметь экземпляр класса A в классе B, чтобы иметь доступ к его свойству делегата.
let classa = ClassA()
classa.delegate = self
последний шаг - просто вызвать метод протокола следующим образом.
func changeBackgroundColor(_ color: UIColor?) {
view.backgroundColor = color
}
В заключение, если вы видите этот метод в своем классе, но у вас нет доступа к реализации протокола, вы спросите себя "откуда этот магический цвет происходит??" но, как вы видели, он просто принадлежит другому классу, которому принадлежит протокол, надеюсь, это поможет.