Всякий раз, когда я добавляю / удаляю элементы из постоянного хранилища, список, источник которого использует результаты FetchRequest.wrappedValue, обновляется, и появляются новые записи / удаленные записи исчезают (с помощью кнопки «Добавить» / проведите пальцем по действию «Удалить»). Это происходит, даже если я не сохраняю контекст. Если я решу сделать сброс контекста после внесения этих изменений без сохранения, мое представление списка будет повреждено - удаленные записи по-прежнему пропадают, а вновь добавленные записи отображаются с неправильными значениями.
Теперь документация Swift действительно говорит о том, что несохраненные управляемые объекты «забываются» после использования reset () в NSManagedObjectContext, который все это объясняет, но мне не удалось обновить список sh. Я могу использовать идентификатор в списке для автоматического обновления sh их значений, но он не добавляет / удаляет отсутствующие записи. Есть ли способ сделать это? Попытка удалить эти «забытые» объекты после сброса контекста вызывает cra sh при следующем сохранении контекста.
Вот код, который я использовал. У меня есть только один объект API с одним атрибутом Id Int32
import SwiftUI
import CoreData
struct test: View {
private var context: NSManagedObjectContext
var request: FetchRequest<API>
var results : FetchedResults<API>{request.wrappedValue}
@State private var refreshingID = UUID()
var body: some View {
VStack {
HStack {
Button(action: {self.APICount()}) {
Text("API count")
}
Spacer()
Button(action: {self.addNewElement()}) {
Text("Add")
}
Spacer()
Button(action: {self.clearList()}) {
Text("Clear")
}
Spacer()
Button(action: {self.saveContext()}) {
Text("Save context")
}
}
Spacer().frame(height: 40)
HStack {
Button(action: {self.reverseChanges()}) {
Text("reset context")
}
Spacer()
Button(action: {self.crash()}) {
Text("crash app")
}
Spacer()
Button(action: {self.checkContext()}) {
Text("context has changes?")
}
}
List {
ForEach(results, id: \.self) { result in
Text("\(result.id)")
}.onDelete(perform: deleteAPI)
}.id(refreshingID)
}
}
private func APICount() {
let NSRequest = NSFetchRequest<API>(entityName: "API")
NSRequest.sortDescriptors = [NSSortDescriptor(keyPath: \API.id, ascending: true)]
do {
try print("count=\(self.context.fetch(NSRequest).count)")
} catch let error {
fatalError(error.localizedDescription)
}
}
private func reverseChanges() {
self.context.reset()
self.refreshingID = UUID()
}
private func checkContext() {
print("checkContext has changes? \(self.context.hasChanges)")
}
private func crash() {
print("before crash has changes? \(self.context.hasChanges)")
fatalError("Crash")
}
private func clearList() {
for api in results {
self.context.delete(api)
}
}
private func deleteAPI(indexes: IndexSet) {
for index in indexes {
self.context.delete(results[index])
}
}
private func addNewElement() -> Void {
let api = API.init(context: self.context)
api.id = Int32(test.getNextID(from: self.context))
}
private func saveContext() {
do {
try self.context.save()
} catch let error {
fatalError(error.localizedDescription)
}
}
public init() {
self.context = test.getMOC()
self.request = FetchRequest<API>(entity: API.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \API.id, ascending: true)])
}
// MARK: - Static functions
static func getMOC() -> NSManagedObjectContext {
guard let context = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext else {
fatalError("Unable to read managed object context.")
}
return context
}
static func getNextID(from context: NSManagedObjectContext) -> Int {
let request = NSFetchRequest<API>(entityName: "API")
request.sortDescriptors = [NSSortDescriptor(keyPath: \API.id, ascending: false)]
request.fetchLimit = 1
do {
return Int(try context.fetch(request).first?.id ?? 0) + 1
} catch let error {
fatalError(error.localizedDescription)
}
}
}