Делегаты - что это такое?


#1

Кто-то может объяснить на пальцах - что такое делегат? Прошел уже множество уроков, писал сложные приложения, но до сих пор самая сложная тема для меня - делегат. Есть множество статей на эту тему, но чем больше читаю - тем больше путаюсь… =( Вот не удается представить себе, что это такое и все. Притом, что опыт программирования более 18 лет…


#2

На пальцах это звучит так. Вы программист - новичок и в команде вас двое, вы и ведущий программист. Ведущий программист уходит в отпуск а вам говорит “Добавишь в приложение кнопку, протестуешь и чай попей” в данном случае он делегировал события, он в данном случае делегат, а вы класс (например) и теперь выполняете его поручения. ИМХО


#3

Если опыт 18 лет, то вам должно быть знакомо слово Interface. Так вот это он и есть, только в свифте называется protocol/delegate.


#4

Даже интересно стало, на чем вы 18 лет программируете?!)

Это как это так) :upside_down_face:
Может конечно я не правильно понял вопрос, но не разу не слышал, что интерфейс это и есть делегат))

пример

Есть необходимые требования к тестировщику, тестировать код, их мы описываем в интерфейсе TesterProtocol

protocol TesterProtocol: class {
    func testCode()
}

Есть тип разработчика, к которому прикреплен тестировщик, разработчику не важно какой именно тестировщик к нему прикреплен. главное, чтобы он умел тестировать код func testCode(), после каждого завершения работы он отправляет код на проверку тестировщику

class Developer {
    weak var tester: TesterProtocol?
    
    func finish() {
        print("DID FINISH CODE")
        tester?.testCode()
    }
}

Например есть какая-то женщина, которая помимо уборки, умеет тестировать код.

class SomeWoman: TesterProtocol {
    func wash() {
        print("Посуда помыта")
    }
    func testCode() {
        print("\(String(describing: Self.self)) Finish Test")
    }
}

Developer в этом объекте интересует только одно, чтобы он определял протокол TesterProtocol

final class FirstWoman: SomeWoman { }
final class SecondWoman: SomeWoman { }

let developer = Developer()
let first = FirstWoman()
developer.tester = first
developer.finish()
DID FINISH CODE
FirstWoman Finish Test

let second = SecondWoman()
developer.tester = second
developer.finish()
DID FINISH CODE
SecondWoman Finish Test

В итоге разработчик делегировал свои обязанности по тестированию кода другим объектам) Как-то так наверно)


#5

вот пример реализации интерфейса в обычном понимании ЯП

interface IFile
{
    void ReadFile();
    void WriteFile(string text);
}

class FileInfo : IFile
{
    public void ReadFile()
    {
        Console.WriteLine("Reading File");
    }

    public void WriteFile(string text)
    {
        Console.WriteLine("Writing to file");
    }
}

Разве не одно и тоже?


#6

Одно и тоже)
так а причем тут делегат!?)


#7

У человека 18 лет опыта, значит ему должно быть понятнее на примере Интерфейса.


#8

аааа)
Боже мой)
Дошло)
Понял вообще не так)


#9

Еще немного и я бы уже стал сомневаться в своих словах ))


#10

Программировал в основном на PHP
Не могу найти схожести с интерфейсами.
Как тогда объяснить такое?

let mapVC = segue.destination as? MapViewController
mapVC.incomeSegueIdentifier = identifier
mapVC.mapViewControllerDelegate = self - Для чего это?


#11

Грубо говоря, это своего рода колбэк. Таким образом self будет получать какие-то команды от MapViewController.


#12

Этот же код у вас в контроллере (классе).
let mapVC = segue.destination as? MapViewController - создали второй контроллер.
mapVC.mapViewControllerDelegate = self. Self - это указание на класс (контроллер), внутри которого находится код. То есть вы назначили делегатом для mapVC первый контроллер, внутри которого у вас этот код.


#13

лучше всего это посмотреть на примере таблицы с данными. Здесь есть группа методов (Data Source) с помощью которых таблица заполняется данными. И вторая группа методов, которая отвечает за оформление таблицы. Например, высота ячейки, цвет фона, шрифт и т.д. Вот эта вторая группа методов и есть делегаты. Что это значит. Дело в том, что таблица это объект и объект может взаимодействовать с другими объектами. Это общее правило в ООП. Но отсюда вытекает и то, что объект не может взаимодействовать сам с собой, поскольку он должен взаимодействовать с другими объектами. Т.е. объект не может сам себя изменять. Поэтому объект шлет сообщение другому объекту и типа говорит, сделай у меня такое-то изменение. В случае с TableView таблица шлет сообщение своему супер вью и он становится ее делегатом. И этот супревью выполняет в данном случае работу по изменению внешнего вида таблицы. В других случаях это могут быть другие действия, которые по каким-то причинам удобнее отдавать делегату. И по ходу предварительно нужно указать какой другой объект будет делегатом. Это может быть не только супер вью, но и какие-то иные объекты.

В вашем случае -

mapVC.mapViewControllerDelegate = self

ваш mapVC назначает себе делегатом свой вью более высокого уровня, или супервью, который в данном случае обозначается сокращением self. Т.е. этот супервью теперь будет обслуживать вашу карту и скорее всего будет как раз изменять ее внешний вид.


#14

А первая группа методов не делегат?


#15

Это пример композиции, как бы самые основы ООП.


#16

вы правы, но для объяснения в данном конкретном случае это лучше пока пропустить.