Kuh*_*ann 13 core-data swift swiftui
我知道 SwiftUI 使用状态驱动渲染。所以我假设,当我删除核心数据实体条目时,我的包含核心数据元素的列表会立即刷新。我使用此代码,它成功地清理了我的实体:
func deleteAll()
{
    let fetchRequest: NSFetchRequest<NSFetchRequestResult> = ToDoItem.fetchRequest()
    let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
    let persistentContainer = (UIApplication.shared.delegate as! AppDelegate).persistentContainer
    do {
        try persistentContainer.viewContext.execute(deleteRequest)
    } catch let error as NSError {
        print(error)
    }
}
为了让我的视图中的列表视觉上为空,我必须在之后离开视图(例如使用“self.presentationMode.wrappedValue.dismiss()”)并再次打开它。好像这些值仍然存储在内存中的某个地方。这当然不是用户友好的,我确信我只是监督了一些可以立即刷新列表的内容。也许有人可以帮忙。
Asp*_*eri 16
原因是execute(如下详述-注意第一句话)不会影响托管对象上下文,因此所有获取的对象都保留在上下文中,而 UI 代表上下文真正呈现的内容。
因此,一般而言,在此批量操作之后,您需要通知该代码(此处未提供)强制同步并重新获取所有内容。
API接口声明
Run Code Online (Sandbox Code Playgroud)// Method to pass a request to the store without affecting the contents of the managed object context. // Will return an NSPersistentStoreResult which may contain additional information about the result of the action // (ie a batch update result may contain the object IDs of the objects that were modified during the update). // A request may succeed in some stores and fail in others. In this case, the error will contain information // about each individual store failure. // Will always reject NSSaveChangesRequests. @available(iOS 8.0, *) open func execute(_ request: NSPersistentStoreRequest) throws -> NSPersistentStoreResult
例如它可能是以下方法(草率)
// somewhere in View declaration
@State private var refreshingID = UUID()
...
// somewhere in presenting fetch results
ForEach(fetchedResults) { item in
    ...
}.id(refreshingID) // < unique id of fetched results
...
// somewhere in bulk delete 
try context.save() // < better to save everything pending
try context.execute(deleteRequest)
context.reset() // < reset context
self.refreshingID = UUID() // < force refresh
Tob*_*ias 13
无需强制刷新,这是 IMO 不是一个干净的解决方案。
正如您在问题中正确提到的,内存中仍有元素。解决方案是在执行后使用mergeChanges.
这篇博文在“更新内存对象”下详细解释了解决方案。
在这里,笔者提供的扩展,NSBatchDeleteRequest如下
extension NSManagedObjectContext {
    
    /// Executes the given `NSBatchDeleteRequest` and directly merges the changes to bring the given managed object context up to date.
    ///
    /// - Parameter batchDeleteRequest: The `NSBatchDeleteRequest` to execute.
    /// - Throws: An error if anything went wrong executing the batch deletion.
    public func executeAndMergeChanges(using batchDeleteRequest: NSBatchDeleteRequest) throws {
        batchDeleteRequest.resultType = .resultTypeObjectIDs
        let result = try execute(batchDeleteRequest) as? NSBatchDeleteResult
        let changes: [AnyHashable: Any] = [NSDeletedObjectsKey: result?.result as? [NSManagedObjectID] ?? []]
        NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [self])
    }
}
以下是有关如何调用它的代码的更新:
func deleteAll() {
    let fetchRequest: NSFetchRequest<NSFetchRequestResult> = ToDoItem.fetchRequest()
    let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
    let persistentContainer = (UIApplication.shared.delegate as! AppDelegate).persistentContainer
    do {
        try persistentContainer.viewContext.executeAndMergeChanges(deleteRequest)
    } catch let error as NSError {
        print(error)
    }
}
在此链接下还有更多信息:Core Data NSBatchDeleteRequest 似乎将对象保留在上下文中。
| 归档时间: | 
 | 
| 查看次数: | 3746 次 | 
| 最近记录: |