Нераспознанный селектор Core Data отправляется экземпляру при попытке доступа к свойству NSSet

Я пытаюсь составить список всех объектов TestItem, но получаю эту ошибку: 'NSInvalidArgumentException', reason: '-[TestItem copyWithZone:]: unrecognized selector sent to instance.

Модель данных

ТестЭлем

Список Тестовых Элементов

TestItemList+CoreDataProperties

import Foundation
import CoreData


extension TestItemList {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<TestItemList> {
        return NSFetchRequest<TestItemList>(entityName: "TestItemList")
    }

    @NSManaged public var name: String?
    @NSManaged public var testitems: NSSet?
    
    public var itemArray: [TestItem] {
        let set = testitems as? Set<TestItem> ?? []
        return set.sorted{
            $0.name! < $1.name!
        }
    }

}

extension TestItemList : Identifiable {
}

ContentView

import SwiftUI
import CoreData

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext

    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \TestItemList.name, ascending: true)],
        animation: .default)
    private var itemLists: FetchedResults<TestItemList>

    @State var listExists: Bool = false
    
    var body: some View {
        NavigationView {
            VStack{
                List{
                    ForEach(itemLists, id: \.self){ List in
                        NavigationLink(destination: ListElementsView(list: List)){
                            Text("\(List.name!)")
                        }
                    }.onDelete(perform: deleteItemList)
                }
                if (listExists){
                    Text("List exists!").foregroundColor(.red)
                }
                Button("Add today's list", action: {
                    addItemList()
                }).disabled(listExists).buttonStyle(.borderedProminent)
                List{
                    ForEach(testitems){
                        item in Text("\(item.name!), \(item.list!.name!)")
                    }
                }
            }
        }
    }
    
    private func addItemList() {
        let dateFormatter : DateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd"
        let date = Date()
        let dateString = dateFormatter.string(from: date)
        
        
        if (!itemLists.contains(where: {$0.name == dateString})){
            let newList = TestItemList(context: viewContext)
            newList.name = dateString
            
            do{
                try viewContext.save()
            } catch {
                let error = error as NSError
                fatalError("Error \(error), \(error.userInfo)")
            }
        }else{
            listExists = true
        }
    }

    private func deleteItemList(offsets: IndexSet) {
        withAnimation {
            offsets.map { itemLists[$0] }.forEach(viewContext.delete)

            do {
                try viewContext.save()
            } catch {
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }
}

private let itemFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateStyle = .short
    formatter.timeStyle = .medium
    return formatter
}()

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
    }
}

ListElementsView

import SwiftUI

struct ListElementsView: View {
    @Environment (\.managedObjectContext) private var viewContext
    
    @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \TestItem.name, ascending: true)], animation: .default)
    private var testitems: FetchedResults<TestItem>

    var list: TestItemList
    
    @State private var text: String = ""
    
    var inputNotOk: Bool{
        text.isEmpty
    }
    
    var body: some View {
        VStack{
            Text(list.name!).font(.largeTitle)
            List{
                ForEach(list.itemArray){
                    obj in Text("\(obj.name!)")
                }.onDelete(perform: deleteTestItem)
            }
            Button("Add item", action: {
                addNewTestItem()
            }).disabled(inputNotOk).buttonStyle(.borderedProminent)
            TextField("item name", text: $text)
        }
    }
    
    private func addNewTestItem(){
        let newItem = TestItem(context: viewContext)
        newItem.name = text
        newItem.list = list
        do{
            try viewContext.save()
        } catch {
            let error = error as NSError
            fatalError("Error \(error), \(error.userInfo)")
        }
    }
    
    private func deleteTestItem(offsets: IndexSet){
        withAnimation{
            offsets.map{testitems[$0]}.forEach(viewContext.delete)
        }
        do{
            try viewContext.save()
        } catch {
            let error = error as NSError
            fatalError("Error \(error), \(error.userInfo)")
        }
    }
}

Если в списке есть элементы, приложение вылетает при входе в ListElementsView. Я могу ввести его, если список пуст.

Я пытался сделать print(type(of: list.testitems)), он возвращает NSSet

Затем я попытался добавить print(list.testitems!.count), приложение вылетает.

Есть идеи?

Не используйте! Вызывает такие ошибки

lorem ipsum 19.06.2023 00:13

В вашем вычисляемом свойстве itemArray вам нужно явно создать массив из вашего набора, а затем отсортировать массив. Сортировка набора не имеет смысла. И массив - это то, что вы говорите, что собираетесь вернуть

Paulw11 19.06.2023 00:15

Не могли бы вы уточнить @Paulw11? Как я могу это сделать? Кроме того, я не думаю, что это проблема. Я нашел этот учебник, и он работает там

Fronk 19.06.2023 03:32

Правильно ли установлен параметр «к одному/ко многим»? И можно объявить все свойства NSManaged необязательными, чтобы избавиться от вопросительных знаков. @Paulw11 Вы можете отсортировать Swift Set. Он возвращает отсортированный массив.

vadian 19.06.2023 06:58

Не называйте переменную List в SwiftUI, это имя встроенного типа, которое сбивает с толку при чтении и, возможно, также может создать проблемы при компиляции.

Joakim Danielson 19.06.2023 08:28
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Оказалось, что vadian в комментариях был прав, я вообще не устанавливал параметр to-one/to-many.

Другие вопросы по теме