如何在Swift中正确使用委托?

时间:2016-03-02 14:11:01

标签: ios swift uiviewcontroller delegates protocols

我读了很多关于代表的内容,但在实践中我无法正确使用它。

说明:我有A: UIViewControllerB: UIViewC: UIViewController。我想将A: UIViewController中的segue从C: UIViewController内部运行到B: UIView

我试过了:

protocol SegueDelegate {
    func runSegue(identifier: String)
}

class B: UIView { ... }

我的A: UIViewController

override func viewDidLoad() {
    B().delegate = self
}

func runSegue(identifier: String) {
    self.performSegueWithIdentifier(identifier, sender: self)
}

并尝试通过以下方式调用它:

@IBAction func send(sender: AnyObject) {
    let a: SegueDelegate? = nil
    a!.runSegue("goToMainPage")
}

但我确定我没有正确使用它。任何人都可以帮助我吗?我不想只是一个答案。请稍后描述一下我的概念

2 个答案:

答案 0 :(得分:1)

代表只是一种可以通过多种方式使用的设计模式。您可以查看Apple框架以查看如何以及在何处使用委托作为示例。表视图委托可能是UIKit中最知名的委托。

代理充当代码的回调机制,以便与未知类的实例进行通信,而不需要知道该实例将响应委托协议的方法。

委托的替代方法是使用闭包(我们在Objective-C中用来调用块)。何时使用一个与另一个是一个品味问题。有几条经验法则,例如outlined here

您正在做的是,IMO,使用代表的正确方法。您通过委托将视图功能与View Controller的功能分开,因此您的视图合同是明确的:用户需要响应委托方法。

您的代码有效且正确无误。我在这里快速实现了:https://github.com/kristofvanlandschoot/DelegateUsage/tree/master

与您的示例的主要区别在于,也许您犯错误的地方是您的代码的第三部分,您应该写下这样的内容:

@IBAction func send(sender: AnyObject) {
    delegate?.runSegue("segueAB")
}

答案 1 :(得分:0)

您的代码中存在多个错误,例如:

在这里,您要创建一个新的B,并将A设置为该新实例的委托,而不是您真正想要的那个

override func viewDidLoad() {
    «B()».delegate = self
}

在这里,你正在创造一个展开零值的力量

@IBAction func send(sender: AnyObject) {
    let a: SegueDelegate? = «nil»
    «a!».runSegue("goToMainPage")
}

如果您想要做的是告诉A从C内部执行到C的segue,您需要做的就是在A上调用performSegueWithIdentifier

例如:

class B: UIView {
    weak var referenceToA: UIViewController? = nil // set this somewhere
    @IBAction func send(sender: AnyObject) {
        guard let a = referenceToA else {
            fatalError("you didn't set the reference to a view controller of class A")
        }
        a.performSegueWithIdentifier("goToMainPage", sender: self)
    }
}