本周早些时候我遇到了一个奇怪的错误,并希望跟进,看看如何防止问题的根本原因。
采取以下代码。
//*****************************
//MAINVIEWCONTROLLER CLASS CODE
//*****************************
//Some event happens that triggers me to want to load up TestViewController.
func showViewController(){
var testController = TestViewController()
testController.someMethod("Test1")
self.navigationController?.pushViewController(testController, animated: true)
}
//*****************************
//TESTVIEWCONTROLLER CLASS CODE
//*****************************
testView:TestView!
override func viewDidLoad(){
super.viewDidLoad()
testView = TestView()
...
}
func someMethod(someData:String){
testView.name = someData //AppCrashes here because testView might be nil.
...
}
所以someMethod
在TestViewController
有机会通过并创建testView
之前就被解雇了。然后我得到一个无法打开可选值的值,因为testView
是nil并且我正在访问它上面的属性。
奇怪的是我正在运行的应用程序可能在6个不同的地方做了这个确切的事情,并且5/6工作得很好,但是1/6现在给了我这个错误。我猜它是因为viewDidLoad
不能保证在执行someMethod
之前立即启动或完成启动,但为什么在所有6个用例中都没有发生这种情况。
所以我的主要问题是:
谢谢!周到的答案将一如既往地起床!如果有更多信息有用,请告诉我。
答案 0 :(得分:1)
由于编写代码甚至不应编译,因为testView是可选的,但您有两个选择。使用选项(在这种情况下,如果未在viewDidLoad之后调用,视图可能无法获取信息,但它不会崩溃)或存储传递的信息并在viewDidLoad或viewWillAppear中更新视图。
您可能想要注意的是viewIfLoaded
答案 1 :(得分:1)
您可以使用with:
强制viewDidLoad方法 var testViewController = TestViewController()
_ = testViewController.view
testViewController.someMethod("Test")
初始化ViewController不会自动调用viewDidLoad
答案 2 :(得分:1)
基本上从不在源控制器调用的目标控制器中运行涉及UI元素的代码。创建属性,在源控制器中设置它,并将值分配给目标控制器的viewDidLoad()
中的UI元素,例如:
//*****************************
//MAINVIEWCONTROLLER CLASS CODE
//*****************************
//Some event happens that triggers me to want to load up TestViewController.
func showViewController(){
var testController = TestViewController()
testController.someData = "Test1"
self.navigationController?.pushViewController(testController, animated: true)
}
//*****************************
//TESTVIEWCONTROLLER CLASS CODE
//*****************************
testView:TestView!
var someData = ""
override func viewDidLoad(){
super.viewDidLoad()
testView = TestView()
testView.name = someData
...
}