Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use delegate and protocol instead of just passing an instance in Swift?

I was trying to pass around variables between views in Swift, and ran into the rather abstract concept of protocols and delegates.

Then I tried storing a reference to the first view in a second view and call functions on that directly. This seems to work:

SCREEN 1

class Screen1: UIViewController {

    var myName = "Screen1"

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    //
    // checking if the segue to screen 2 is called and then passing a reference
    //
    override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
        if segue.identifier == "screen2Segue"{
            let vc = segue.destinationViewController as Screen2
            vc.storedReference = self
        }
    }

    func getName() -> String {
        return myName
    }
}

SCREEN 2

class Screen2: UIViewController {

    var storedReference:Screen1!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func testReference() {
        // calling a function on the stored reference to screen 1
        var str = storedReference.getName()
        println("Leaving screen 2, going to " + str)
    }
}

My question: what's wrong with this code? Why use delegates and protocols if you can just pass around a reference directly?

Perhaps related: when does a view get un-initialized and replaced by an entirely new view instance? Am I calling 'getName()' on an old instance?

like image 745
Kokodoko Avatar asked Jul 25 '14 16:07

Kokodoko


People also ask

Why do we use delegates in Swift?

In Swift, a delegate is a controller object with a defined interface that can be used to control or modify the behavior of another object.

What is the difference between delegate and protocol in Swift?

We can say Protocol as a set of rules. That rules can be optional or required like we have to use in protocol. Delegates is a message passing technique in objective C and swift. An object has to take care of that message.

Why do we use protocol in Swift?

Swift checks for protocol conformity issues at compile-time, allowing developers to discover some fatal bugs in the code even before running the program. Protocols allow developers to write flexible and extensible code in Swift without having to compromise the language's expressiveness.

Can delegation be implemented without a protocol Swift?

You don't have to use protocols...but you should if you want to keep things flexible. Delegation is in essence asking someone else to do something for you. If you enforce a contract, then its more likely they will do it for you.


2 Answers

Protocols are useful for separating implementation from interface, which helps increase code reusability, understandability, and testability.

For example, perhaps you wish to store items in a List of some sort. Some possible implementations of a List include array-based implementations and node-based (linked-list) implementations. If you were to declare a protocol called List and have classes ArrayList and LinkedList that implemented that protocol, anything that required the use of a list (variable passed as a parameter to a method, a property, etc) could use List as the variable type, and be able to function without caring about whether a the list was an ArrayList or a LinkedList. You could change which type was used, or how they were implemented, and it would not matter to whatever was using them, because only the exposed interface declared in the protocol would be visible.

Protocols can also be useful for emulating something like multiple inheritance, as a class can inherit from a superclass, as well as implement one or more interfaces. (eg. A bat is both a mammal and winged, so it could be represented as a Bat class inheriting from a Mammal class that implements the Winged protocol).

The delegate pattern uses protocols to delegate some responsibilities to another object, which is especially good for code separation and reusability. For example, the UITableViewDelegate protocol in iOS allows a UITableView to react to things like cell selection by delegating another object to handle the event. This has probably been used by millions of objects in thousands of applications, without the developers at Apple who implemented UITableView and UITableViewDelegate having ever known anything about the objects that were implementing the protocol.

By directly passing a reference between your view controllers, you are forcing the second to be completely dependent upon the first. If you ever wished to change the flow of your application so that the second view controller could be accessed from somewhere else, you would be forced to rewrite that view controller to use the new origin. If you use a protocol instead, no changes to the second view controller would have to be made.

like image 137
Kamaros Avatar answered Sep 28 '22 01:09

Kamaros


It is a basic design principle to not expose any more of a design than you have to. By passing the reference around you are exposing the whole object. Which means that others can call any of its functions and access any of its properties. And change them. This isn't good. Besides letting others use the object in ways it might not have intended, you will also run into issues if you try to change the object in the future and find out that it breaks somebody else who was using something you didn't intend. So, always a good idea to not expose anything that you don't have to. This is the purpose of delegates and protocols. It gives the object complete control over what is exposed. Much safer. Better design.

like image 35
hcanfly Avatar answered Sep 28 '22 03:09

hcanfly