简体   繁体   English

Swift 委托和协议

[英]Swift delegate & protocols

For protocols and delegates to work, do the view controllers have to be adjacent in the stack?为了使协议和委托工作,视图控制器是否必须在堆栈中相邻? The function called by my delegate was working fine until I inserted a new vc in between the vc sending the data and the vc receiving them.我的代表调用的 function 工作正常,直到我在发送数据的 vc 和接收数据的 vc 之间插入了一个新的 vc。 (If the answer is, "Of course, you idiot." I'd actually be relieved as I'm really stumped.) (如果答案是,“当然,你这个白痴。”我真的会松一口气,因为我真的很难过。)

Presumably, you have something like this:大概,你有这样的事情:

在此处输入图像描述

and your code runs along these lines:并且您的代码按照以下方式运行:

protocol MyCustomDelegate: class {
    func myFunc(_ value: Int)
}

class VC1: UIViewController, MyCustomDelegate {
    
    func myFunc(_ value: Int) {
        print("value: \(value)")
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? VC2 {
            vc.delegate = self
        }
    }
}

class VC2: UIViewController {
    
    weak var delegate: MyCustomDelegate?
    
    func someAction(_ sender: Any?) -> Void {
        delegate?.myFunc(1)
    }
    
}

Now, you "insert a new VC" :现在,你“插入一个新的 VC”

在此处输入图像描述

So your code in VC1 is no longer segueing to VC2 ... and thus the delegate won't be set.因此,您在VC1中的代码不再与VC2绑定……因此不会设置委托。

One approach, not necessarily the best, would be:一种方法,不一定是最好的,是:

  • add a delegate var in VC1A , which is set by VC1VC1A中添加一个委托变量,由VC1设置
  • when navigating from VC1A to VC2 , pass that delegate alongVC1A导航到VC2时,传递该委托

It could look something like this:它可能看起来像这样:

protocol MyCustomDelegate: class {
    func myFunc(_ value: Int)
}

class VC1: UIViewController, MyCustomDelegate {
    
    func myFunc(_ value: Int) {
        print("value: \(value)")
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? VC1A {
            vc.delegate = self
        }
    }

}

class VC1A: UIViewController {
    
    weak var delegate: MyCustomDelegate?
    
    func someAction(_ sender: Any?) -> Void {
        delegate?.myFunc(1)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? VC1A {
            vc.delegate = self.delegate
        }
    }

}

class VC2: UIViewController {
    
    weak var delegate: MyCustomDelegate?
    
    func someAction(_ sender: Any?) -> Void {
        delegate?.myFunc(1)
    }
    
}

If your app flow is simple enough, this would probably work... but, it's not ideal and is prone to problems as your code gets more complex.如果您的应用程序流程足够简单,这可能会起作用......但是,它并不理想,并且随着您的代码变得更加复杂容易出现问题。

You may want to re-think how your code is structured, and how you're trying to manage your data.您可能需要重新考虑代码的结构,以及您尝试管理数据的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM