https://refactoring.guru/design-patterns

Delegate

Em Swift, o termo "delegate" refere-se a um padrão de design conhecido como Delegate Pattern. O Delegate Pattern é uma maneira de permitir que um objeto delegue responsabilidades ou comportamentos para outro objeto. Isso é comumente usado para permitir a comunicação entre objetos em um sistema orientado a objetos.

Em Swift, para criar e usar delegates, você normalmente segue os seguintes passos:

  1. Defina o protocolo do delegate:

    
    protocol MyDelegate: AnyObject {
        func didSomething()
    }
    
  2. Declare uma propriedade delegada na classe principal:

    
    class MyClass {
        weak var delegate: MyDelegate?
    
        func performAction() {
            // Faça alguma coisa...
    
            // Notifique o delegado quando algo acontecer
            delegate?.didSomething()
        }
    }
    
    
  3. Conforme o protocolo no delegado:

    
    class MyDelegateClass: MyDelegate {
        func didSomething() {
            // Lide com a ação que ocorreu
            print("Something happened!")
        }
    }
    
    
  4. Atribua o delegado à instância principal:

    
    let myObject = MyClass()
    let delegateObject = MyDelegateClass()
    
    myObject.delegate = delegateObject
    
    

Agora, quando performAction é chamado em myObject, ele notificará o delegado (se houver algum) chamando o método didSomething no delegado.

Lembre-se de usar weak ao declarar a propriedade do delegado para evitar ciclos de retenção fortes que podem levar a vazamentos de memória. O uso de weak é particularmente importante se o delegado for uma referência forte ao objeto que o contém.

Exemplo de utilização

Vamos criar um exemplo simples de uso do padrão de design Delegate em Swift. Vamos supor que temos um botão (Button) que precisa notificar um objeto externo quando é pressionado. Vamos usar um protocolo chamado ButtonDelegate para definir a interface do delegado.


// Definindo o protocolo do delegate
protocol ButtonDelegate: AnyObject {
    func buttonPressed()
}

// Classe do botão que aceita um delegado
class Button {
    // Declarando a propriedade delegada
    weak var delegate: ButtonDelegate?

    // Método chamado quando o botão é pressionado
    func pressButton() {
        print("Button pressed")

        // Notificando o delegado, se existir
        delegate?.buttonPressed()
    }
}

// Classe que age como delegado e conforma ao protocolo
class ButtonDelegateClass: ButtonDelegate {
    func buttonPressed() {
        print("Delegate notified: Button pressed action handled")
    }
}

// Uso do exemplo
let button = Button()
let delegateObject = ButtonDelegateClass()

// Atribuindo o delegado ao botão
button.delegate = delegateObject

// Pressionando o botão
button.pressButton()

Neste exemplo:

  1. Definimos um protocolo chamado ButtonDelegate que contém um método buttonPressed().
  2. A classe Button possui uma propriedade delegada do tipo ButtonDelegate e um método pressButton() que imprime uma mensagem indicando que o botão foi pressionado e notifica o delegado chamando delegate?.buttonPressed().
  3. A classe ButtonDelegateClass implementa o protocolo ButtonDelegate e fornece uma implementação para o método buttonPressed(), que imprime uma mensagem indicando que a ação do botão foi tratada.
  4. Criamos uma instância do botão, uma instância do delegado e atribuímos o delegado ao botão. Em seguida, chamamos pressButton() no botão, que notifica o delegado, se existir.