NSFetchRequest returns .count 的错误值

NSFetchRequest returns wrong value of .count

在我使用 SwiftUI 作为界面的应用程序中,我有一个执行操作的按钮:

func getBooksCountNumber() -> Int {
    var countResult = 0
    let booksFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Book")
    
    do {
        let booksFetch = try self.persistentContainer.viewContext.fetch(booksFetch) as! [Book]
        countResult = booksFetch.count
        print("countResult is \(countResult)")
    } catch {
        fatalError("Failed to fetch: \(error)")
    }

    return countResult
}

当我在应用程序中删除行时,我使用 moc.delete(book)try? moc.save()。我看到删除的行消失了,使用 icloud.developer.apple.com 处的界面。例如 — 如果我从 3 条记录中删除 1 条,我仍然在 countResult 中得到 3 而不是 2。感谢任何帮助。

SwiftUI 依靠数据失效来强制 View 重新加载。

因此您需要考虑如何让您的 View 代码依赖于数据的变化,例如 countResult(作为示例)。

如果您使用的是 SwiftUI,我建议您考虑使用 @FetchRequest 属性 包装器来获取您的数据集...

@FetchRequest(entity: Book.entity(),
              sortDescriptors: []
) var books: FetchedResults<Book>

注意:sortDescriptors: 参数是必需的,因此如果您不想对 FetchedResults 进行排序,请包含一个空数组 [].

然后使用与该包装器关联的 属性 将数据提供给您的视图...

struct YourView: View {
    // @FetchRequest here
    var body: some View {
        ...
        Text("Book count = \(books.count)")
        ...
    }
}

这样,您甚至不需要按按钮来确定计数,因为每次在您的 Book 实体中添加或删除一本书时,Text 视图都会更新.

采用SwiftUI方式编写,随着数据变化,Text视图组件会失效,视图struct会被强制重绘

如果您想将按钮保留在您的视图中,您可以改为执行类似的操作...

    var body: some View {
        ...
        Button(action: {
            // code to perform your action here...
        }) {
            Text("You have \(books.count) books")
        }
        ...
    }

按钮的标签包括书籍数量(按钮执行其他操作)。