在这个视图中,如果我试图发送另一个视图,比如CartItem(),那么应用程序就会崩溃,并出现错误线程1:"Object Has be Delete or Inaliated".如果我再次进入这个应用程序,卡蒂泰姆就会被删除! 我认为宾语是一些在哪里使用的东西

import Foundation
import RealmSwift

class ApiResponse: Decodable {
    let status: Bool
    let page: String
    let category: String
    let results: [Product]
}

class Product: Object, Identifiable, Decodable {
    @Persisted var product_id: String
    @Persisted var product_name: String
    @Persisted var product_price: String
    @Persisted var product_group: String
    @Persisted var product_description: String
    @Persisted var product_thumb_images: String
    @Persisted var product_big_images: String
    @Persisted var isInCart: Bool = false
//    @Persisted var quantity: Int = 1 // Default quantity is 1

    enum CodingKeys: String, CodingKey {
        case product_id, product_name, product_price, product_group, product_description, product_thumb_images, product_big_images
    }
    
    override class func primaryKey() -> String? {
        return "product_id"
    }
}

class CartItem: Object,Identifiable {
    @Persisted var product: Product?
    @Persisted var quantity: Int = 1

    convenience init(product: Product, quantity: Int) {
        self.init()
        self.product = product
        self.quantity = quantity
    }
}

import Foundation
import Alamofire
import SwiftUI
import RealmSwift
import Realm

class ProductViewModel: ObservableObject {
    @Published var products: [Product]?
    @Published var errorMessage: String?
    @Published var cartItems: [CartItem] = []
    @Published var selectedCategory: String = "All"

    internal func fetch() {
        let urlString: String
        if selectedCategory == "All" {
            urlString = ""
        } else {
            urlString = ""
        }
        guard let url = URL(string: urlString) else {
            self.errorMessage = "Invalid URL"
            return
        }

        AF.request(url)
            .validate()
            .responseDecodable(of: ApiResponse.self) { response in
                switch response.result {
                case .success(let apiResponse):
                    self.products = apiResponse.results
                case .failure(let error):
                    self.errorMessage = "Error fetching data: \(error)"
                }
            }
    }

    func addToCart(product: Product) {
        do {
            let realm = try Realm()

            if let existingProduct = realm.object(ofType: Product.self, forPrimaryKey: product.product_id) {
                try realm.write {
                    if existingProduct.isInCart {
                        if let existingCartItem = cartItems.first(where: { $0.product?.product_id == product.product_id }) {
                            existingCartItem.quantity += 1
                        } else {
                            // Create a new CartItem with quantity 1
                            let cartItem = CartItem(product: existingProduct, quantity: 1)
                            realm.add(cartItem)
                        }
                    } else {
                        // Update the isInCart property and add to cart
                        existingProduct.isInCart = true
                        // Create a new CartItem with quantity 1
                        let cartItem = CartItem(product: existingProduct, quantity: 1)
                        realm.add(cartItem)
                    }
                }
            } else {
                // Product does not exist in the database, handle accordingly
                // Create a new CartItem with quantity 1
                let cartItem = CartItem(product: product, quantity: 1)
                try realm.write {
                    realm.add(cartItem)
                }
            }

            updateCartItems()
        } catch {
            print("Error adding to cart: \(error)")
        }
    }



    func removeFromCart(product: Product) {
        do {
            let realm = try Realm()
            if let existingCartItem = cartItems.first(where: { $0.product?.product_id == product.product_id }) {
                if existingCartItem.quantity > 1 {
                    try realm.write {
                        existingCartItem.quantity -= 1
                    }
                } else {
                    // Update the isInCart property and remove from cart
                    if let existingProduct = existingCartItem.product {
                        try realm.write {
                            existingProduct.isInCart = false
                        }
                    }
                    try realm.write {
                        realm.delete(existingCartItem)
                    }
                }
                updateCartItems()
            }
        } catch {
            print("Error removing from cart: \(error)")
        }
    }


    internal func updateCartItems() {
        do {
            let realm = try Realm()
            cartItems = Array(realm.objects(CartItem.self))
        } catch {
            print("Error updating cart items: \(error)")
        }
    }

    func calculateTotalPrice() -> Double {
        return cartItems.reduce(0) { $0 + Double($1.quantity) * Double($1.product?.product_price ?? "0")! }
    }
}

//
//  AddCartView.swift
//  ZED_Shop
//
//  Created by JARVIS on 22/12/23.
//

import SwiftUI

struct AddCartView: View {
    @ObservedObject var viewModel: ProductViewModel

    var body: some View {
        NavigationView {
            VStack {
                if viewModel.cartItems.isEmpty {
                    Text("Your cart is empty.")
                } else {
                    List {
                        ForEach(viewModel.cartItems) { cartItem in
                            VStack() {
                                HStack {
                                    VStack{
                                        Text(cartItem.product?.product_name ?? "Unknown Product")
                                            .font(.smallCaps(.title3)())
                                            .frame(maxWidth: .infinity, alignment: .leading)
                                            .padding(.top)
                                            .padding(.leading)
                                        Text("\(cartItem.product?.product_price ?? "0")")
                                            .font(.title)
                                            .fontWeight(.bold)
                                            .frame(maxWidth: .infinity, alignment: .leading)
                                            .padding(.leading)
                                            .foregroundColor(.blue)
                                        Text("\(cartItem.quantity)")
                                            .foregroundColor(.black)
                                            .padding(.bottom)
                                    }
                                    Spacer()
                                    HStack{
                                        RemoteImage(url: URL(string: cartItem.product!.product_thumb_images))
                                            .frame(width: 130, height: 170)
                                    }
                                }
                            }
                        }
                        .onDelete(perform: { indexSet in
                            viewModel.removeFromCart(product: viewModel.cartItems[indexSet.first!].product!)
                        })
                    }
                }

                Text("Total Price: \(viewModel.calculateTotalPrice())")

                Button("Checkout") {
                    // Handle checkout logic
                }
                .disabled(viewModel.cartItems.isEmpty)
            }
            .navigationTitle("Cart")
            .onAppear {
                viewModel.updateCartItems() // Fetch cart items on appear
            }
        }
    }
}

struct AddCartView_Previews: PreviewProvider {
    static var previews: some View {
        return AddCartView(viewModel: ProductViewModel())
    }
}

import SwiftUI
import RealmSwift

struct CartItemView: View {
    @ObservedObject var viewModel: ProductViewModel
    let cartItem: CartItem
    let product: Product
    var body: some View {
        HStack {
            VStack(alignment: .leading) {
                HStack {
                    Text(cartItem.product?.product_name ?? "Unknown Product")
                        .font(.smallCaps(.title3)())
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .padding(.top)
                        .padding(.leading)
                    Spacer()
                    Button(action: {
                        // Handle delete action
                        withAnimation {
                            viewModel.removeFromCart(product: cartItem.product!)
                        }                 }) {
                            Image(systemName: "trash")
                                .foregroundColor(.red)
                        }
                        .padding(.top)
                        .padding(.trailing)
                        .frame(width: 25, height: 25)
                    Spacer()
                }
                
                Text("₹\(String(format: "%.2f", viewModel.calculateTotalPrice()))")
                    .font(.title)
                    .fontWeight(.bold)
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .padding(.leading)
                    .foregroundColor(.blue)
                
                HStack {
                    Button(action: {
                        // Decrease quantity action

                    }) {
                        Text("-")
                            .frame(width: 50, height: 50)
                            .background(.blue.opacity(0.1))
                            .cornerRadius(10)
                            .foregroundColor(.black)
                    }
                    
                    .padding(.bottom)
                    .padding(.leading, 20)
                    Spacer()
                    
                    Text("\(cartItem.quantity)")
                        .foregroundColor(.black)
                        .padding(.bottom)
                    
                    Spacer()
                    Button(action: {
                        // Increase quantity action
                    }) {
                        Text("+")
                            .frame(width: 50, height: 50)
                            .background(.blue.opacity(0.1))
                            .cornerRadius(10)
                            .foregroundColor(.black)
                    }
                    
                    .padding(.bottom)
                    Spacer()
                }
                .frame(maxWidth: 200)
                
                Spacer()
                
            }
            .frame(maxWidth: .infinity)
            .frame(height: 170)
            
            RemoteImage(url: URL(string: cartItem.product!.product_thumb_images))
                .frame(width: 130, height: 170)
                .frame(alignment: .trailing)
            
        }
        .frame(maxWidth: .infinity)
        .frame(height: 170)
        .background(Color.gray.opacity(0.1))
        .cornerRadius(10)
        .shadow(color: Color.black.opacity(0.1), radius: 5, x: 0, y: 2)
        .padding(.leading)
        .padding(.trailing)
    }

}

请给我这个问题的解决方案

我想在AddtoCartView中添加CartItem,如下所示

struct AddCartView: View {
    @ObservedObject var viewModel: ProductViewModel

    var body: some View {
        NavigationView {
            VStack {
                if viewModel.cartItems.isEmpty {
                    Text("Your cart is empty.")
                } else {
                    List {
                        ForEach(viewModel.cartItems) { cartItem in
                            VStack() {
                                CartItemView(
                                    viewModel:viewModel,
                                    cartItem: cartItem, product: cartItem.product!
                                )
                            }
                        }
                        .onDelete(perform: { indexSet in
                            viewModel.removeFromCart(product: viewModel.cartItems[indexSet.first!].product!)
                        })
                    }
                }

                Text("Total Price: \(viewModel.calculateTotalPrice())")

                Button("Checkout") {
                    // Handle checkout logic
                }
                .disabled(viewModel.cartItems.isEmpty)
            }
            .navigationTitle("Cart")
            .onAppear {
                viewModel.updateCartItems() // Fetch cart items on appear
            }
        }
    }
}

struct AddCartView_Previews: PreviewProvider {
    static var previews: some View {
        return AddCartView(viewModel: ProductViewModel())
    }
}

推荐答案

因为这是SwiftUI,所以不应该有视图模型对象,这是视图 struct 层次 struct 的工作.状态应该分散在小的View struct 中,其中let用于只读,@Binding用于读/写,您不应该在每个View中都有@ObservedObject,这会使它变得缓慢,并可能解释它崩溃的原因.try 重命名并将ProductViewModel拆分为ProductFetcher/CartFetcher,只包含获取代码并从中删除所有视图数据,例如selectedCategory.

Ios相关问答推荐

当重新呈现UI时,嵌套的 struct 值如何与@Observable一起工作?

IFrame内容拒绝仅在iOS浏览器上加载-即使发布了内容-安全-策略(CSP)框架-祖先指令

为什么iOS委派在KMM中不能正常工作?

如何使用参与者允许并行读取,但阻止对SWIFT中资源的并发读取和写入?

使用标头UICollectionViewFlowLayout时的简单SwiftUI视图错误

如何在expo-react native中从ios平台中排除包

Flutter应用内购买无法恢复购买

使用 Objective-C 创建 iOS 框架

保存和读取登录到 keys 串不工作 IOS swift

Swift:判断 Foundation (NS)Errors 与自定义协议的一致性

在视图控制器中实例化视图控制器是否可能/智能?

使用 Vim 代替(或与)Xcode 进行 iOS 开发

无法同时满足约束 - 没有适当的约束

在代码生成的 UIView 上绘制 UIBezierPath

无法将NSTaggedPointerString类型的值转换为NSNumber

如何在 iOS 中判断暗模式?

如何使用 Contacts Framework 获取 iOS 9 中的所有联系人记录

正确的领域使用模式/最佳实践?

Parse for iOS:try 运行应用程序时出错

SwiftUI 应用生命周期 iOS14 AppDelegate 代码放哪里?