Segue传值后才执行observe?Utente结构体跨控制器共享问题
问题根源:异步执行的Firebase回调
你遇到的问题本质是Firebase的observe方法是异步执行的——主线程会先跑完所有同步代码(包括你那行Segue数据传递的代码),而Firebase的网络请求是在后台线程处理的,等数据返回触发闭包时,Segue早就完成了,这时候你传递的ut自然还没被正确赋值。
解决方案:手动控制Segue触发时机
解决思路很简单:等Firebase数据拿到并解析完成后,再手动触发Segue,而不是依赖Storyboard的自动Segue。具体步骤如下:
1. 调整Segue触发方式
如果你的Segue是通过Storyboard拖拽(比如按钮直接关联Segue),先取消这个关联:
- 选中Storyboard里的Segue,按Delete删除
- 给触发Segue的按钮添加一个
IBAction(比如按钮点击事件)
2. 在Firebase回调内触发Segue
在按钮的点击事件里,先发起Firebase数据请求,等数据解析完成后再手动调用Segue:
@IBAction func navigateToChatTapped(_ sender: UIButton) { // 假设uid是你要获取的用户ID let userRef = Database.database().reference().child("utenti").child(uid) // 用observeSingleEvent只获取一次数据(如果不需要实时监听的话) userRef.observeSingleEvent(of: .value) { [weak self] snapshot in guard let self = self else { return } // 解析snapshot到你的Utente结构体 guard let userData = snapshot.value as? [String: Any], let utente = Utente(from: userData) else { // 假设你有对应的初始化方法 print("用户数据解析失败") // 这里可以给用户弹个提示框 return } // 保存解析后的用户数据 self.ut = utente // 手动触发Segue,注意替换成你的Segue标识符 self.performSegue(withIdentifier: "GoToChatSingola", sender: self) } }
3. 在prepare方法中传递数据
这时候在prepare(for:sender:)里,ut已经被正确赋值了,直接传递即可:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { guard segue.identifier == "GoToChatSingola" else { return } if let chatsingola = segue.destination as? ChatSingola { chatsingola.aaa = self.ut } }
额外注意事项
- 如果需要实时监听用户数据变化,再用
observe(.value),否则优先用observeSingleEvent,避免多次触发Segue - 一定要处理数据解析失败的情况(比如snapshot为空、数据格式不匹配),给用户明确的反馈,避免无意义的跳转
- 用
[weak self]避免循环引用,防止内存泄漏
内容的提问来源于stack exchange,提问作者Simone Armanni
相关产品推荐
相关产品推荐

