The definition that made most sense was from developer.apple.com. “Delegation is a mechanism by which a host object embeds a weak reference to another object (its delegate) and periodically sends messages to the delegate when it requires its input for a task.”

For example, NSWindow has a weak reference to its delegate object, delegate, which conforms to the protocol NSWindowDelegate. NSWindowDelegate defines a set of optional methods that the delegate can implement to respond to various messages sent by the window object. Since the methods are optional, NSWindow will check if its delegate implemented them by calling respondToSelector.

Motivation

Why delegation? why can’t we use inheritance instead? Delegation reduces coupling between classes. There is no need for our object to subclass NSWindow in order to define additional behavior. We just become a delegate of NSWindow to receive all the critical messages we’re interested in and then define our own custom behaviors on top of it.

Example

This is an extremely simple example to see how delegation might work. Suppose we have a view with a simple button. When the button is pressed, we move to another view. In the first view controller we have the following:

class ViewController: UIViewController, SubViewControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
        button.backgroundColor = .green
        button.setTitle("Press", for: .normal)
        button.addTarget(self, action: #selector(pressed), for: .touchUpInside)
        self.view.addSubview(button)
    }
	@objc func pressed() { // when the button is pressed, move to AnotherViewController
        let host = HostViewController()
        host.delegate = self // we are the delegate of host
        self.present(sub, animated: true, completion: nil)
    }
}

In the second view controller (host), we have a button. When we press the button, we want to let the first view controller know that it’s been pressed. To do so, we create a weak delegate reference that lives with us, the host controller. This delegate must conform to a protocol that we design. someMessage is the way we want to communicate with the delegate.

public protocol HostViewControllerDelegate: class {
    func someMessage(_ message: String)
}

The delegate will implement someMessage. The host will then call someMessage on the delegate to pass it a message that says “hey, the button has been pressed!!”.

class HostViewController: UIViewController {
    public weak var delegate: HostViewControllerDelegate? // our delegate

    override func viewDidLoad() {
        let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
        button.backgroundColor = .red
        button.setTitle("World", for: .normal)
        button.addTarget(self, action: #selector(pressed), for: .touchUpInside)
        self.view.addSubview(button)
    }

    @objc func pressed() {
        delegate?.someMessage("hey, the button has been pressed!!")
    }
}


References