试图在Swift中了解带有协议的委托的实现

时间:2016-08-05 10:12:45

标签: ios swift design-patterns delegates

在做了大量的研究后,我仍然对如何使用和实现委托感到困惑。我曾尝试编写自己的简化示例,以帮助我理解 - 但它不起作用 - 这意味着我必须有点迷失。

//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();

我已阅读并观看过如此多的教程,但仍在努力。我不再得到错误(欢呼的家伙)。但仍然没有得到sayName的输出。

这表明我必须误解委托模式是如何工作的。 我真的很感激代码的更正版本,并简单解释了为什么它的工作原理,以及为什么它有用。

我希望这对其他人也有帮助。欢呼声。

1 个答案:

答案 0 :(得分:2)

在Swift中你省略了第一个参数的外部名称,所以你的函数调用应该是delegate.sayName("Tom")

此外,正如您所发现的那样,对delegate属性使用隐式展开的可选项是危险的。你应该使用弱选项:

//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)
    }
}

最后,您的代理人必须是一个对象,因此您无法以您展示的方式使用代理人;您需要创建另一个可以将自身实例设置为委托

的类
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()

输出:

  

在委托功能中,名称为Tom