SwiftUI中PostRepository的householdID赋值后调用addVote时为空求助
看起来你踩了一个很常见的实例管理坑——你正在使用两个完全独立的PostRepository对象,这就是为什么addVote里的householdID是空的。
问题根源拆解
你在页面的onAppear里初始化的是self.postListVM.postRepository这个实例的householdID,打印时能看到值是正确的;但调用addVote时,你用的是另一个全新创建的@Published var postRepository = PostRepository()实例。这两个对象毫无关联,后者的householdID自然还是初始的空字符串。
解决方案
我给你两种靠谱的解决思路,从根本上避免这类问题:
1. 确保全程使用同一个PostRepository实例
如果你的PostRepository是由ViewModel(比如postListVM)管理的,那所有调用它方法的地方都应该复用ViewModel里的那个实例,而不是自己新建。
比如,把调用addVote的代码改成:
// 不要用自己新建的postRepository,复用ViewModel里的实例 postListVM.postRepository.addVote(post: yourPost, option: yourOption, counter: yourCounter)
同时要确保ViewModel实例在整个页面流程中是唯一的:可以用@StateObject创建ViewModel,或者通过EnvironmentObject在视图间传递,避免重复创建ViewModel导致PostRepository也跟着被重新初始化。
2. 优先通过构造函数注入依赖(更推荐)
既然householdID是PostRepository正常工作必需的参数,那最好在创建实例的时候就传入,而不是事后调用initHousehold补值。这种方式能从根源上避免忘记初始化或者实例不一致的问题。
修改PostRepository的代码:
class PostRepository: ObservableObject { // 改成非可选类型,明确这个值必须存在 let householdID: String // 在初始化时直接传入householdID init(householdID: String) { self.householdID = householdID print(self.householdID) // 这里就能看到正确的值 } func addVote(post: Post, option: Int, counter: Int) { print(self.householdID) // 现在肯定不会是空的了 } }
然后在ViewModel里创建PostRepository时就传入householdID:
class PostListVM: ObservableObject { @Published var postRepository: PostRepository init(session: Session) { // 从session获取householdID,直接初始化PostRepository let householdID = session.session?.householdID ?? "" self.postRepository = PostRepository(householdID: householdID) } }
这样一来,你甚至不需要在onAppear里调用initHousehold了,PostRepository从诞生起就拥有有效的householdID,所有调用它方法的地方都能拿到正确的值。
额外提醒
如果你在多个视图中需要使用PostRepository,建议把它(或者它所在的ViewModel)通过EnvironmentObject注入到视图层级中,这样所有子视图都能拿到同一个实例,彻底避免实例重复创建的问题。
内容的提问来源于stack exchange,提问作者Markus STZ

