You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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")
})

问题原因

  1. 多实例冲突:应用中存在多个StocksData或CartManager实例。从打印的库存数据差异(Sugar的amount分别为300和500)可以看出,pay函数操作的是一个独立的StocksData实例,而StockInput视图操作的是另一个实例。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 18:15:59