SwiftUI中CartManager无法识别代码添加的自定义库存问题
问题
程序逻辑如下:向StocksData添加库存,向另一数组添加自定义产品;调用pay函数时,库存的amount会扣除产品的折旧量。但pay函数仅能识别手动初始化的库存,无法识别通过代码添加的自定义库存;当产品库存名称匹配时,预期的库存扣减操作无法执行。
已通过打印验证:自定义产品在其他视图的stocksData数组中能正常显示,但CartManager的pay函数打印的数组里只有初始库存。打印输出如下:
[(name: "Sugar", amount: 300, unit: "g")] Project400.StocksData Project400.StocksData [(name: "Sugar", amount: 500, unit: "g"), (name: "S", amount: 100, unit: "g")] Project400.StocksData
相关代码
StocksData类
class StocksData: ObservableObject { @Published var stocks: [(name: String, amount: Int, unit: String)] = [] init() { // 示例初始化数据,可替换为实际逻辑 stocks.append(("Sugar", 500, "g")) } }
CartManager类
class CartManager: ObservableObject { @Published var stocksData: StocksData @Published var productData = ProductData() // 补充原代码缺失的product属性声明 var product: Product init(stocksData: StocksData, product: Product) { self.stocksData = stocksData self.product = product print(stocksData) } func pay() { print(stocksData.stocks) if let productStockName = product.stockName, let index = stocksData.stocks.firstIndex(where: { $0.name == productStockName }) { var stock = stocksData.stocks[index] if let depreciatedAmount = product.depreciatedAmount { stock.amount -= depreciatedAmount stocksData.stocks[index] = stock } } } }
StockInput视图
Button(action: { self.stocksData.stocks.append((name: self.stockName, amount: self.stockAmount, unit: self.units[self.unitSelection])) let cartManager = CartManager(stocksData: self.stocksData) }, label: { Text("Add Stock") })
问题原因
- 多实例冲突:应用中存在多个
StocksData或CartManager实例。从打印的库存数据差异(Sugar的amount分别为300和500)可以看出,pay函数操作的是一个独立的StocksData实例,而StockInput视图操作的是另一个实例。 - CartManager未共享:每次点击"Add Stock"时都会新建
CartManager实例,但实际调用pay函数的是之前创建的另一个CartManager,导致新添加的库存无法被感知。
解决方案
1. 全局共享唯一实例
在App入口创建唯一的StocksData和CartManager实例,并通过Environment传递给所有需要的组件:
@main struct YourApp: App { @StateObject private var stocksData = StocksData() @StateObject private var cartManager: CartManager init() { // 假设Product有默认初始化方式,可根据实际情况调整 _cartManager = StateObject(wrappedValue: CartManager(stocksData: stocksData, product: Product())) } var body: some Scene { WindowGroup { ContentView() .environmentObject(stocksData) .environmentObject(cartManager) } } }
2. 视图中使用共享实例
修改StockInput视图,不再新建CartManager,直接通过Environment获取全局共享实例:
struct StockInputView: View { @EnvironmentObject var stocksData: StocksData @EnvironmentObject var cartManager: CartManager // 其他属性:stockName、stockAmount、units、unitSelection等 var body: some View { Button(action: { stocksData.stocks.append((name: stockName, amount: stockAmount, unit: units[unitSelection])) // 无需新建CartManager,共享实例会自动感知库存变化 }, label: { Text("Add Stock") }) } }
3. 验证数据一致性
此时CartManager持有与视图相同的StocksData实例,调用pay函数时会自动获取最新的库存数据,完成预期的扣减操作。
内容的提问来源于stack exchange,提问作者Ryan Malone
相关产品推荐
相关产品推荐

