ios - 尝试了解 Swift 中使用协议(protocol)的委托(delegate)的实现

标签 ios swift design-patterns delegates

经过大量研究后,我仍然对如何使用和实现委托(delegate)感到困惑。我尝试编写自己的简化示例来帮助我理解 - 但它不起作用 - 这意味着我一定有点迷路。

//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 得到任何输出。

这表明我一定是误解了委托(delegate)模式的工作原理。 我真的很感激代码的更正版本,并简单解释它为什么有效,为什么有用。

我希望这对其他人也有帮助。干杯。

最佳答案

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

最后,你的委托(delegate)必须是一个对象,所以你不能像你展示的那样使用委托(delegate);您需要创建另一个可以将其自身的实例设置为委托(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()

输出:

In the delegate function, the name is Tom

关于ios - 尝试了解 Swift 中使用协议(protocol)的委托(delegate)的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38786708/

相关文章:

ios - 如何将按钮添加到文本末尾,如 Facebook 的 "Continue reading"?

ios - 使用 swift 在 ReactiveCocoa 中进行 flattenMap 和错误处理

javascript - IIFE 在防止名称冲突方面比 "named function declaration"有何优势?

android - 安全性:应用程序源代码中的谷歌客户端 secret 安全吗?

iOS:多行 UILabel 与水平 UIStackView 中的另一个 UILabel 的大小错误

swift - 如何从 NWEndpoint.service 枚举案例解析地址和端口信息(如果可能)

java - 仅包含具有内部状态的静态成员的类

oop - 从全局状态转移到依赖注入(inject)等模式的好机制是什么?

ios - 将双重值(value)保存到核心数据有时会保存完全错误的值(value)

ios - 在后台模式下关闭我的应用程序后将下载简历