iOS开发中通过Storyboard实例化ViewController传值后变量始终为空如何排查
传值失效的核心原因基本都是对象引用不对或者赋值时机不对,逐点排查就行:
先检查赋值取到的源值是不是空
代码里写的viewController2.testName = TextFieldOutlet.text!,如果你把这段实例化、传值的逻辑写在viewDidLoad这类过早的生命周期里,此时文本框还没完成内容加载,text属性本身就是空值;哪怕用户已经输入了内容,只要文本框的IBOutlet连线断了,TextFieldOutlet是nil,强行解包直接就会触发崩溃,根本走不到赋值环节。
排查很简单:在赋值行后面加个打印,看看实际传给testName的值是不是真的拿到了用户输入的内容,避免无意义的排查。最常见的踩坑:出现两个独立的ViewController2实例
很多人写完代码实例化、赋值的逻辑之后,跳转还是靠Storyboard里预先拖好的自动segue。这种场景下,触发跳转时系统会重新创建一个全新的VC2实例用来展示,你之前在代码里手动赋值的那个VC2对象从头到尾都没有被加到视图栈里,新展示的VC2里的testName自然就是代码里写的默认空串值,label自然也显示不出来内容。
解决方法不要混用两种跳转逻辑,二选一就行:- 全程走代码跳转:实例化VC2、完成赋值之后,立刻把VC2通过push或者present的方式展示出来,不要额外加Storyboard的自动segue,参考正确的代码流程:
guard let viewController2 = self.storyboard? .instantiateViewController(withIdentifier: "ViewController2") as? ViewController2 else { fatalError("找不到对应控制器,请检查Storyboard ID是否拼写正确") } viewController2.testName = TextFieldOutlet.text ?? "" // 赋值完成立刻执行跳转,中间不要插其他异步逻辑 self.navigationController?.pushViewController(viewController2, animated: true)- 全程走Storyboard segue跳转:删掉所有手动实例化VC2的代码,在
prepare(for:sender:)代理方法里拿到系统即将展示的目标VC2实例再赋值,这种方式拿到的引用和最终展示的对象是同一个,传值不会失效。
检查Storyboard配置匹配度
确认你代码里通过self.storyboard取到的文件,和你配VC2的Storyboard ID、连label的IBOutlet的文件是同一个。如果两个配置分属不同的Storyboard文件,哪怕类型转换通过了,赋值也不会作用到最终展示的对象上。
内容的提问来源于stack exchange,提问作者Louis Raverdy

