Should you use swift closure or delegate?

Have you ever wanted to implement something but you have multiple options to achieve the same thing? That’s the issue here. It’s a good kind of problem but can be tiring at times. 😀

Let’s say you have a ViewController1 that launches ViewController2. Also, ViewController1 will like to know when an action in ViewContoller2 succeeds or fails. You can use closures or make use of delegate functions. Which one will you go for?

In this article, we are going to discuss, at what point closures or delegate seem appropriate when communicating between two ViewControllers. Feel free to use the comments section to drop comments about what you think about it and what works best for you.

Here is my opinion…


First, using both closures and delegate are memory safe if treated well to be. That is basically using a [weak self] for your closure and weak var when declaring your delegate to create a weak reference.

//MARK:- CLOSURE

class ViewController1 : UIViewController { 
    
    let viewController2 = ViewController2(nibName: "ViewController2", bundle: nil)
    viewController2.successCallback = { [weak self] in
        //Do something
    }
}


class ViewController2: UIViewController {
    var successCallback: () -> Void = {}
}
//MARK:- DELEGATE

class ViewController1 : UIViewController, ViewController2Delegate { 
    
    let viewController2 = ViewController2(nibName: "ViewController2", bundle: nil)
    viewController2.delegate = self
    
    func onSuccess() {
        //Do something
    }
}


protocol ViewController2Delegate: class {
    func onSuccess()
}

class ViewController2: UIViewController {
    weak var delegate: ViewController2Delegate?
}

Both methods above make sure the closure and the calling ViewController are not tightly coupled, making sure the ViewController can be disposed of when needed.

Closure

Below are the scenarios where I find closures okay, and also the times when it becomes really not okay.

When to use:

I believe closures can be used anytime really. Surprised? Closures are powerful and ideal for keeping everything in one place.

When not to use:

Once I begin to have more than two closures in certain circumstances, it might begin to make the codebase look dirty and hard to read, so I opt-in for delegate. In case you don’t have all the closures you need yet, try and think of later and picture what it would be like when you have like four or more closures all littered across a function, for instance, it could become messy. You can opt-in for delegate in that case.

Delegate

Let’s take a look at scenarios where delegate seems okay and cases where it doesn’t.

When to use:

Delegate can really come in handy anytime, like any time. Especially when you need many functions to be called.

When not to use:

Just like closures might make code become messy when overused, delegate might appear to be an ‘overkill’ for small objectives, like when it has only one delegate function.
Imagine you create a protocol, create a delegate reference, link it up, implement the protocol function(s), all for just one function? Well, sometimes, a simple closure could suffice. Not to say delegate can’t be used with just one function, if a simple closure can replace it, then that’s cool.


Let me know what you think and what works best for you. Feel free to drop your comments 🤗