harry lakins
harry lakins

Reputation: 843

Trying to understand the implementation of delegates with protocols in Swift

After doing loads of research I am still a little confused about how to use and implement delegates. I have tried writing my own, simplified example, to aid my understanding - however it does not working - meaning I must be a little lost.

//the underlying protocol
protocol myRules {
    func sayName(name: String);
}

//the delegate that explains the protocols job
class myRulesDelegate: myRules {
    func sayName(name: String){
        print(name);
    }
}

//the delegator that wants to use the delegate
class Person{
    //the delegator telling which delegate to use
    weak var delegate: myRulesDelegate!;
    var myName: String!;

    init(name: String){
        self.myName = name;
    }
    func useDels(){
        //using the delegate (this causes error)
        delegate?.sayName(myName);
    }
}

var obj =  Person(name: "Tom");
obj.useDels();

I have read and watched so many tutorials but am still struggling. I no longer get error (cheers guys). But still get no output from sayName.

which demonstrates I must be misunderstanding how delegate patterns work. I would really appreciate a corrected version of the code, with a simple explanation as to why it works, and why it is helpful.

I hope this helps others too. Cheers.

Upvotes: 1

Views: 88

Answers (1)

Paulw11
Paulw11

Reputation: 114826

In Swift you omit the first parameter's external name, so your function call should be delegate.sayName("Tom")

Also, it is dangerous to use an implicitly unwrapped optional for your delegate property, as you have found. You should use a weak optional:

//the underlying protocol
protocol MyRulesDelegate: class {
    func sayName(name: String)
}

//the delegator that wants to use the delegate
class Person {
    //the delegator referencing the delegate to use
    weak var delegate: MyRulesDelegate?
    var myName: String

    init(name: String){
        self.myName = name
    }

    func useDels() {
        //using the delegate
        delegate?.sayName(myName)
    }
}

Finally, your delegate must be an object, so you can't use a delegate in the way you have shown; you need to create another class that can set an instance of itself as the delegate

class SomeOtherClass: MyRulesDelegate {

    var myPerson: Person

    init() {
        self.myPerson = Person(name:"Tom")
        self.myPerson.delegate = self
    }

    func sayName(name: String) {
        print("In the delegate function, the name is \(name)")
    }
}


var something = SomeOtherClass()
something.myPerson.useDels()

Output:

In the delegate function, the name is Tom

Upvotes: 2

Related Questions