The primary principle of Delegate

Analysis of the Delegate principle

In class B, a method needs to pass a value to A and perform certain actions.

How can this be implemented?

First, B needs to know who to pass the value to and then call A.aFunc().

I understand that you want to know the principle without looking at the code, so I’ll simplify it as much as possible.

Classes A and B

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
A.swift
class A {
func aFunc(b: B) {
println(b.value)
}
}

B.swift
class B {
var value = 0
func bFunc() {
value = 213 // The value changes and we want to notify A to execute aFunc()
a.aFunc(b) // Error
}
}

The above code doesn’t work, why?
Because there is no reference to A in class B, if we pass A directly, we’ll have to modify class B’s code, and thus lose the encapsulation.

Let’s see how Delegate can implement this mechanism:

Delegate

Since B needs to send a message externally, let’s start with B:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
A.swift
class A {
func aFunc(b: B) {
println(b.value)
}
}

B.swift
protocol BDelegate {
func aFunc(b: B) // 1. Declare aFunc from A as a method of BDelegate
}

class B {
var delegate: BDelegate? // 2. Declare a delegate variable of type BDelegate
var value = 0
func bFunc() {
value = 213
delegate?.aFunc(self) // 3. Call aFunc() with self (b) as the parameter
}
}

After steps 1, 2, and 3, it still won’t work, why?
Because A doesn’t know that B has delegated the task, they’re not connected.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
A.swift
class A: BDelegate { // 1. BDelegate
func aFunc(b: B) {
b.delegate = self // 2. Set the delegate variable of b as self, which is a
println(b.value)
}
}

B.swift
protocol BDelegate {
func aFunc(b: B)
}

class B {
var delegate: BDelegate?
var value = 0

func bFunc() {
value = 213
delegate?.aFunc(self) // 3. Do you understand now? delegate?.aFunc(self) is equivalent to a.aFunc(b)
}
}

main.swift
let b = B()
let a = A()
a.aFunc(b)
b.bFunc()

// You can observe the results in a Playground

Success!

Think about common code snippets, like:

1
2
3
4
5
mScrollView.delegate = self
...
class MYScrollView: UIScrollView, UIScrollViewDelegate {
...
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {

Do you feel enlightened now?

I’ll talk about SEL and Block in a couple of days.


I feel like I haven’t explained it clearly, so if you have any questions or need further clarification, feel free to leave a comment and we can discuss it.

Translated by gpt-3.5-turbo