Swift3 Swift委派:在展开可选值时意外发现nil

Swift3 Swift委派:在展开可选值时意外发现nil,swift3,delegates,runtime-error,optional,Swift3,Delegates,Runtime Error,Optional,编辑:请注意下面的问题讨论了在 2个同样在UITabBarController中实现的视图控制器。 我在这里和YouTube上做了不少搜索,但没有看到我的问题在其他地方被复制。我会说到点子上的 我有两个我自己编码的视图控制器——不是由XCode生成的;TabOneController和TabtowController 下面是这两个的编码 import UIKit class TabOneController: UIViewController{ private let instan

编辑:请注意下面的问题讨论了在 2个同样在UITabBarController中实现的视图控制器。

我在这里和YouTube上做了不少搜索,但没有看到我的问题在其他地方被复制。我会说到点子上的

我有两个我自己编码的视图控制器——不是由XCode生成的;TabOneController和TabtowController

下面是这两个的编码

import UIKit

class TabOneController: UIViewController{


    private let instanceOfTabOneView = TabOneView()

    var vc1Delegate: fromOneToTwo!

    override func loadView() {

        super.loadView()

            view.addSubview(instanceOfTabOneView.buildTheVu())
                view.backgroundColor = UIColor.white

        runThisOnce()

        }

    func runThisOnce(){

        vc1Delegate.passTheValue(heroNameIs: "pass this to TabTwoController")

    }

}

protocol fromOneToTwo{

    func passTheValue(heroNameIs: String)

}
至于表2

import UIKit

class TabTwoController: UIViewController, fromOneToTwo{


    private let instanceOfTabTwoView = TabTwoView()


    override func loadView() {

        super.loadView()

            view.addSubview(instanceOfTabTwoView.buildTheVu())

        assignDelegateToSelf()

    }

    func assignDelegateToSelf(){

        let instanceTabOne = TabOneController()
            instanceTabOne.vc1Delegate = self

    }

    func passTheValue(heroNameIs:String){

        instanceOfTabTwoView.txtFld.text = heroNameIs

    }

}
我在运行时遇到以下错误-应用程序成功构建-

致命错误:在展开可选值时意外发现nil

在下面一行

vc1Delegate.passTheValue(heroNameIs: "pass this to TabTwoController")
当我注释掉上面这一行时,应用程序成功构建并运行,但当然应用程序不会执行委托

我有点理解编译器想告诉我的是

vc1Delegate
还没有被实例化-我猜-。但我在每一块岩石下都搜索了一遍,似乎找不到如何绕过它


我将感谢任何帮助或指导。抱歉,如果我的代码看起来不成熟,我对Swift和一般编程都是新手。谢谢。

UITabBarController
中,默认情况下第一个选项卡正在实例化。视图控制器初始化执行
loadView
并找到
nil
,因为第二个选项卡尚未初始化;这是正常的行为。我的建议是使用
后缀使委托弱可选,并在其他地方运行委托代码。此外,始终将类和协议名称中的第一个字母大写

weak var vc1Delegate: FromOneToTwo?

如果此结构是必需的,请尝试使用自定义通知观察者。

首先,您的错误发生在
var vc1Delegate:fromonetwopassTheValue
时,代码>。正确的做法是正确的

var vc1Delegate: fromOneToTwo?

func runThisOnce(){
    if let delegate = vc1Delegate {
        vc1Delegate.passTheValue(heroNameIs: "pass this to TabTwoController")
    }
}
其次,您没有正确使用委托。在
assignDelegateToSelf()
函数中,您正在创建
TabOneController

然后指派代表。相反,您需要找出现有的
TabOneController
实例并分配委托

谢谢你的答复。我将创建一个带有2个常规ViewController的Xcode项目,并用变量替换任何UI控件。如果问题出在我身上,我会再发一条评论。感谢您的时间。如何找到现有的
TabOneController
实例?@Sebastian,这取决于您的代码是如何编写的。。。如果您想要代理调用,您必须为控制器注册代理,然后您只能接收来自该控制器的代理调用。通常,如果您使用情节提要和普通序列来创建新的视图控制器,则不需要考虑这一点,因为您将只有一个视图控制器实例。但是,当您以编程方式创建视图控制器时(如从序列图像板函数初始化调用),您只需启动一次并将该瞬间存储在某个位置,以便以后可以找到它并接收调用。感谢您的解释。我可以在触发segue时将当前的viewcontroller类保存在一个变量中,然后在segue期间将该变量传递给另一个视图控制器