为啥 @FetchRequest 在 ContentView 中失败

Posted

技术标签:

【中文标题】为啥 @FetchRequest 在 ContentView 中失败【英文标题】:Why @FetchRequest fails in ContentView为什么 @FetchRequest 在 ContentView 中失败 【发布时间】:2020-12-22 21:37:06 【问题描述】:

我的 SwiftUI ContentView 中有以下代码

struct ContentView: View 

@State private var search = ""
@State private var selectedBookID: Int64? = 0

@FetchRequest(entity: Books.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Books.bokName, ascending: true)])
var books: FetchedResults<Books>

var body: some View 
    NavigationView 
        VStack 
            HStack 
                NavigationLink("New book...", destination: BookView(isNew: true)).padding(.leading)
                Spacer()
                NavigationLink("Authors...", destination: AuthorView())
                NavigationLink("Genres...", destination: GenreView()).padding(.trailing)
            .padding(.vertical)
            TextField("Search...", text: $search).padding(.horizontal)
            List(books, id: \Books.bokID, selection: $selectedBookID)  book in
                NavigationLink(book.bokName!, destination: BookView(isNew: false)).buttonStyle(PlainButtonStyle())
            

        
    


并且它在应用程序启动期间失败并出现错误“任何模型中没有 NSEntityDescriptions 声称 NSManagedObject 子类 'Books' 所以 +entity 被混淆了。你加载你的 NSManagedObjectModel 了吗?”。 它适用于同一应用程序中的所有其他视图。 请注意,它是 macOS 应用程序。 谢谢。

【问题讨论】:

尝试清理项目,然后重新构建。通常会为 CoreData 解决此类问题,因为 CoreData 会为您创建模型。 我通过 XCode 中的产品菜单清理了构建文件夹。我还删除了 DerivedData 中的整个项目文件夹并重新启动了 Xcode,但错误仍然存​​在。在我看来,我尝试在 CoreData 堆栈完全初始化之前访问它,因为非常相似的代码在其他视图中运行良好:问题只是 ContentView。 只是想仔细检查一下,不是\Books.bokName的拼写吗?您似乎多次将“book”拼写为“bok”,但我不确定是不是拼写错误。 我知道你来自,但 bokName 是正确的名字。 【参考方案1】:

我找到了方法 - 只需将 @FetchRequest 部分从 ContentView 中取出并将其放入额外的结构中,如下所示

struct ContentView: View 

var body: some View 
    NavigationView 
        VStack 
            HStack 
                NavigationLink("New book...", destination: BookView(isNew: true)).padding(.leading)
                Spacer()
                NavigationLink("Authors...", destination: AuthorView())
                NavigationLink("Genres...", destination: GenreView()).padding(.trailing)
            .padding(.vertical)
            BookList()
        
    



struct BookList: View 

@State private var search = ""
@State private var selectedBookID: Int64? = 0

@FetchRequest(entity: Books.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Books.bokName, ascending: true)])
var books: FetchedResults<Books>

var body: some View 
    TextField("Search...", text: $search).padding(.horizontal)
    List(books, id: \Books.bokID, selection: $selectedBookID)  book in
        NavigationLink(book.bokName!, destination: BookView(isNew: false)).buttonStyle(PlainButtonStyle())
    


【讨论】:

以上是关于为啥 @FetchRequest 在 ContentView 中失败的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 中限制 FetchRequest 中的结果数

SwiftUI - 如何在 init 中使用 fetchRequest 更新数据

两个 ManagedObjectContexts 上的一个 FetchRequest

SwiftUI在FetchRequest中使用带有结构参数的谓词

如何修复错误:@FetchRequest 中的“属性初始化程序在”自我“可用”之前运行

根据表达式在 fetchrequest 中创建列