【问题标题】:Assigning a delegate from a non parent View Controller从非父视图控制器分配委托
【发布时间】:2019-02-22 14:07:22
【问题描述】:

我在 Swift 4 中的协议和委托方面有点挣扎。我将尽我所能描述/向你展示我所拥有的。

主视图控制器:(MVC) 1. 我有主视图控制器类 (MVC)。 VC 具有我想从另一个 ViewController 类 (AVC) 访问的选项属性

class ViewController: UIViewController {
var options: Options?


 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if (segue.identifier == "To Statements") {
        // pass data to next view
        let vc = segue.destination
        let statementVC = vc as! StatementsViewController
        statementVC.coreDataStack = coreDataStack
        statementVC.currentPerson = currentPerson

    }
}

extension ViewController: FormateStatementDelegate {

   // formatting protocol
   func addStatementFormat() -> Int {
     // here is where I would use the options var that is found in the (MVC)
   }
}

语句视图控制器:(SVC) 2.我有一个从(MVC)调用的View Controller类Statement ViewController(SVC)。我正在使用 prepare for segue 函数来设置这个视图控制器(MVC)。

    class StatementsViewController: UIViewController{

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if (segue.identifier == "Add Statement") {
        // pass data to next view
        //print("segue to add statement")
        let vc = segue.destination
        let addStatementVC = vc as! AddStatementViewController
        addStatementVC.coreDataStack = coreDataStack
        addStatementVC.personName = currentPerson!.name!    
    }
    }

AddStatement 视图控制器 (AVC) 3. 我有第三个视图控制器类 AddStatement 视图控制器 (AVC),它是从 (SVC) 调用的。我也在使用 prepare for segue func 从(SVC)设置这个视图控制器

这个类有一个我在 (MVC) 中定义的协议。

protocol FormateStatementDelegate {
func  func addStatementFormat() -> Intmal
}

class AddStatementViewController: UIViewController{
   var delegate FormateStatementDelegate! = nil
}

我感到困惑的是在哪里设置委托属性。我见过的例子似乎在准备 seguer 函数中设置了委托属性。但是由于 (MVC) 是符合 FormateStatementDelegate 协议的协议,我将在哪里以及如何在 (AVC) 中设置委托,因为它们没有父/子关系。我希望我已经以有意义的方式解释了这一点。

【问题讨论】:

  • 您是否尝试将委托设置为 self ?正如你在扩展 viewController 中实现的那样?

标签: swift delegates swift-protocols


【解决方案1】:

您的委托被声明为隐式展开的可选:

class AddStatementViewController: UIViewController{
   var delegate FormateStatementDelegate! = nil
}

对此要小心。如果您忘记设置委托,应用程序将崩溃。 strong retention cycle 也有可能导致内存泄漏。我使用的一般模式是将其声明为弱可选:

protocol FormateStatementDelegate: class {
    ...
}

class AddStatementViewController: UIViewController{
    weak var delegate: FormateStatementDelegate?

    func doSomething() {
        delegate?.addStatementFormat() // This statement will do nothing if delegate is nil
    }
}

现在谈谈你的问题:如果我正确理解你的问题描述,segue 顺序是这样的:

ViewContorller -> StatementViewController -> AddStatementViewController

并且AddStatementViewController 有一个委托,ViewController 符合。您只需要在第二个视图控制器中保存对 MainViewController 实例的引用:

class ViewController: UIViewController {

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
        if (segue.identifier == "To Statements") {
            // pass data to next view
            let vc = segue.destination
            let statementVC = vc as! StatementsViewController
            statementVC.coreDataStack = coreDataStack
            statementVC.currentPerson = currentPerson
            statementVC.formateStatementDelegate = self
        }
    }
}

class StatementViewController {
    weak var formateStatementDelegate: FormateStatementDelegate?

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if (segue.identifier == "Add Statement") {
            // pass data to next view
            //print("segue to add statement")
            let vc = segue.destination
            let addStatementVC = vc as! AddStatementViewController
            addStatementVC.coreDataStack = coreDataStack
            addStatementVC.personName = currentPerson!.name!    
            addStatementVC.delegate = formateStatementDelegate
        }
    }
}

【讨论】:

  • 如果我将其设置为弱引用,我会收到此错误:'weak' must not be applied to non-class-bound 'formatCurrencyDelegate'; consider adding a protocol conformance that has a class bound
  • 所以我基本上必须传递一个引用才能使用没有直接父/子关系的委托?
  • 我不认为委托处于父子关系中。这里的中心思想是保持对委托对象的引用,无论是通过实例变量(如图所示)还是通过导航堆栈以获得正确的。
猜你喜欢
  • 2021-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-26
  • 2013-10-26
  • 2013-06-04
相关资源
最近更新 更多