首页 > 解决方案 > 为什么保存托管对象上下文更改 isDeleted 值?

问题描述

我正在使用 SwiftUI 和 Core Data 编写一个 iOS 应用程序。我对 Core Data 很陌生,并试图理解一些东西:

为什么尝试 self.moc.save()self.item.isDeletedtrue更改为false?它发生在我删除核心数据对象(isDeleted 更改为 true)之后,但稍后保存托管对象上下文将其更改为 false。这是为什么?

这是一个例子:

内容视图.swift

import SwiftUI

struct ContentView: View {
    
    @Environment(\.managedObjectContext) var moc
    var fetchRequest: FetchRequest<Item>
    var items: FetchedResults<Item> { fetchRequest.wrappedValue }
    
    var body: some View {
        
        NavigationView {
            List {
                ForEach(items, id: \.self) {item in
                    
                    NavigationLink(destination: DetailsView(item: item)) {
                        Text("\(item.name ?? "default item name")")
                    }
                    
                }
            }
            .navigationBarTitle("Items")
            .navigationBarItems(
                leading:
                Button(action: {
                    for number in 1...3 {
                        let item = Item(context: self.moc)
                        item.date = Date()
                        item.name = "Item \(number)"
                        
                        do {
                            try self.moc.save()
                        }catch{
                            print(error)
                        }
                    }
                }) {
                    Text("Add 3 items")
                }
            )
        }
    }
    
    init() {
        fetchRequest = FetchRequest<Item>(entity: Item.entity(), sortDescriptors: [
            NSSortDescriptor(keyPath: \Item.name, ascending: true)
        ])
    }
}

DetailsView.swift

import SwiftUI

struct DetailsView: View {
    
    @Environment(\.managedObjectContext) var moc
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    var item: Item
    
    var body: some View {
        
        VStack {
            Text("\(item.name ?? "default item name")")
        }
        .navigationBarItems(
            trailing:
            Button(action: {
                self.moc.delete(self.item)
                print(self.item.isDeleted)

                self.presentationMode.wrappedValue.dismiss()
                print(self.item.isDeleted)
                
                do {
                    try self.moc.save()
                    print(self.item.isDeleted)
                }catch{
                    print(error)
                }
                
            }) {
                Text("Delete")
                    .foregroundColor(.red)
            }
        )
        .onDisappear {
            print(self.item.isDeleted)
            if !self.item.isDeleted {
                print(self.item.isDeleted)
                self.item.name = "new name"
                print(self.item.isDeleted)
                do {
                    try self.moc.save()
                }catch{
                    print(error)
                }
            }
            
        }
        
    }
}

我预期会发生的事情:

  1. self.moc.delete(self.item)将删除一个对象并将self.item.isDeleted标记为 true。
  2. 尝试 self.moc.save将保存 moc
  3. if !self.item.isDeleted如果项目被删除,将阻止代码执行(没有这个,我得到一个错误:Mutating a managed object (...) after it has been removed)

它没有用。我在几行上添加了print(self.item.isDeleted)并在这些行上添加了断点,以检查到底发生了什么。

发生的事情是这样的:

  1. self.moc.delete(self.item)删除了一个对象并将self.item.isDeleted标记为 true。
  2. 尝试 self.moc.save保存的 moc 和...
  3. self.item.isDeleted更改为 false
  4. if !self.item.isDeleted没有阻止代码执行,因为此时 isDeleted 为 false。

它是一个错误吗?或者我不理解 Core Data 对象的生命周期和 isDeleted 的变化?

标签: swiftcore-dataswiftuimanagedobjectcontext

解决方案


为什么要尝试 self.moc.save() 将 self.item.isDeleted 从 true 更改为 false?它发生在我删除核心数据对象(isDeleted 更改为 true)之后,但稍后保存托管对象上下文将其更改为 false。这是为什么?

它的行为与记录的一样 -在保存之前返回true ,而不是在其他情况下

这是 Apple 文档的快照NSManagedObject

概括

一个布尔值,指示在下次保存期间是否将 删除托管对象。宣言

var isDeleted: Bool { get } 讨论

如果 Core Data 将在下一次保存操作期间要求持久存储删除对象,则为 true,否则为 false。它可能在其他时候返回 false,尤其是在对象被删除之后。它将停止返回 true 的即时性取决于对象在被删除过程中的位置。如果接收器出现故障,则访问此属性不会导致其触发。


推荐阅读