【问题标题】:SwiftUI: deleting Managed Object from cell view crashes app?SwiftUI:从单元格视图中删除托管对象崩溃应用程序?
【发布时间】:2022-07-29 13:25:11
【问题描述】:

我有以下代码,我只是修改了 Xcode 为您创建的示例 SwiftUI 项目。

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext

    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
        animation: .default)
    private var items: FetchedResults<Item>

    var body: some View {
        NavigationView {
            List {
                ForEach(items) { item in
                    NavigationLink {
                        Text(item.timestamp!, formatter: itemFormatter)
                    } label: {
                        CellView(item: item)
                    }
                }
                .onDelete(perform: deleteItems)
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    EditButton()
                }
                ToolbarItem {
                    Button(action: addItem) {
                        Label("Add Item", systemImage: "plus")
                    }
                }
            }
            Text("Select an item")
        }
    }

    private func addItem() {
        withAnimation {
            let newItem = Item(context: viewContext)
            newItem.timestamp = Date()

            do {
                try viewContext.save()
            } catch {
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }

    private func deleteItems(offsets: IndexSet) {
        withAnimation {
            offsets.map { items[$0] }.forEach { item in
                viewContext.delete(item)
            }

            do {
                try viewContext.save()
            } catch {
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }
}

struct CellView: View {
    
    @Environment(\.managedObjectContext) private var viewContext
    @ObservedObject var item:Item
    
    var body: some View {
        
        HStack {
            Text(item.timestamp!, formatter: itemFormatter) // <<- CRASH ON DELETE
            Button {
                withAnimation {
                    viewContext.delete(item)
                    try? viewContext.save()
                }
                
            } label: {
                Text("DELETE")
                    .foregroundColor(.red)
            }
            .buttonStyle(.borderless)
        }
        
    }
    
}

private let itemFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateStyle = .short
    formatter.timeStyle = .medium
    return formatter
}()

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
    }
}

Item 是这样定义的:

extension Item {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Item> {
        return NSFetchRequest<Item>(entityName: "Item")
    }

    @NSManaged public var timestamp: Date?

}

extension Item : Identifiable {

}

当我通过滑动或按删除按钮删除项目时,应用程序崩溃。如果我取消 CellView 并将所有代码直接放在导航链接中......它不会崩溃。

如何在保留单独的CellView 的同时解决此问题?

到目前为止我学到了什么:

如果我改变:

@ObservedObject var item:Item

到:

@State var item:Item

崩溃消失了。有什么想法吗?

【问题讨论】:

    标签: ios swift core-data swiftui


    【解决方案1】:

    尽量避免强制解包选项和使用条件(视图生成器现在允许这样的构造)

    HStack {
      if let timestamp = item.timestamp {
        Text(timestamp, formatter: itemFormatter)
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多