"Объект NSManagedObject класса" className "должен иметь допустимое значение NSEntityDescription". ошибка

Я создал простую сущность 'CDWorkout' с одним атрибутом 'name' внутри CDModel.xcdatamodeld. Название контейнера в AppDelegate также является "CDModel". Класс Codegen для "CDWorkout" - это категория/расширение. Вот код для класса CDWorkout:

class CDWorkout: NSManagedObject {

    class func createWorkout(workoutInfo : Workout, in context: NSManagedObjectContext) -> CDWorkout{
        let workout = CDWorkout(context: context)
        workout.name = "anyName"
        return workout
    }
}

функция createWorkout вызывается из другого viewController с аргументом контекста как container.viewContext, но сразу же сбрасывается с сообщением:

Завершение приложения из-за неперехваченного исключения "NSInvalidArgumentException", причина: "NSManagedObject класса" Workout_Generator.CDWorkout "должен иметь допустимое значение NSEntityDescription.

Чего я забыл?

Ответ 1

Проблема заключалась в том, что я не проверил Class Module: текущий модуль продукта для CDWorkout Entity.

Ответ 2

В моем случае такая же проблема была в модификаторе @objc в автоматически сгенерированном заголовке класса данных.

@objc(CachedMovie)
public class CachedMovie: NSManagedObject {

Я только что удалил @objc(CachedMovie) и он начал работать

Ответ 3

У меня была глупая незначительная проблема, которая привела к той же ошибке. Я инициализировал NSPersistentContainer с неправильным именем.

Он должен иметь то же имя, что и исходный файл с расширением .xcdatamodeld. например modelFileName.xcdatamodelId

let persistentContainer = NSPersistentContainer(name: "modelFileName")

Ответ 4

Я столкнулся с этим же сообщением об ошибке при попытке вставить/добавить управляемый объект из расширения (SiriKit). Похоже, что проблема с пространством имен расширения не соответствует файлу .xcdatamodeld, потому что я создавал описание сущности с помощью MyClass.entity().

Сочетание, которое сработало для меня, было:

  • @objc(MyClass) в верхней части каждого подкласса NSManagedObject
  • Объекты в модели данных используют по умолчанию "Глобальное пространство имен", а не "Текущий модуль продукта"
  • Создайте описание сущности с помощью let entity = NSEntityDescription.entity(forEntityName: "MyClass", in: context)!

Ответ 5

enter image description here в вашем файле modeldataClass, вероятно, имя класса неверно, прежде чем вы измените имя в классе имени

Ответ 6

Вам нужно создать новый NSManagedObject, прежде чем вы сможете его использовать

let workout = NSEntityDescription.insertNewObjectForEntityForName("CDWorkout",
    inManagedObjectContext: context) as! CDWorkout

теперь вы можете установить имя так же, как и вы: workout.name = "any_name"

вы можете обратиться к Документация CoreData для получения дополнительной информации о CoreData​​p >

Ответ 7

У меня была аналогичная проблема в стеке CoreData с NSManagedObjectModel, сделанным из кода Swift. Проблема была в неправильном значении для атрибута NSEntityDescription.managedObjectClassName. Префикс Swift module был пропущен.

Правильная настройка:

let entity = NSEntityDescription()
entity.name = PostEntity.entityName // `PostEntity`
entity.managedObjectClassName = PostEntity.entityClassName // `MyFrameworkName.PostEntity`
entity.properties = [....]

Где: entityName и entityClassName определены следующим образом.

extension NSManagedObject {

    public static var entityName: String {
        let className = NSStringFromClass(self) // As alternative can be used `self.description()` or `String(describing: self)`
        let entityName = className.components(separatedBy: ".").last!
        return entityName
    }

    public static var entityClassName: String {
        let className = NSStringFromClass(self)
        return className
    }

}

Ответ 8

Я пытался добавить CoreData в существующий проект, и я много переименовал вещи. Я закончил с несколькими .xcdatamodeld, не зная об этом. Решением было удаление .xcdatamodeld, создание NSManagerObject и повторное его создание.

Ответ 9

легко ответить на этот вопрос. без удаления

@objc(Workout)

решение заключается в документальном программировании базовых данных " имя объекта и имя класса ". здесь, в вашем XCode, прежде чем делать (EditorCreate NSManagedObject SubClass) необходимо изменить имя класса вашего объекта, чтобы добавить "MO", CoreData может различать имя класса и имя объекта. и

@objc(Workout) 

не будет создан, дайте нам это:

class CDWorkoutMO: NSManagedObject {

 class func createWorkout(workoutInfo : Workout, in context: NSManagedObjectContext) -> CDWorkoutMO {
    let workout = CDWorkoutMO(context: context)
    workout.name = "anyName"
    return workout
}
}

как я делаю на своем XCode

Ответ 10

Ошибка, которую я сделал, состояла в том, чтобы изменить имя сущности и сгенерированный "NSManagedObject Subclass", а не обновить имя класса. Как исправить:

  • открыть .xcdatamodeld
  • нажмите на объект
  • откройте правую панель
  • Перейти к инспектору моделей данных
  • Изменить имя текстового поля класса

Ответ 11

Если вы используете coreData из статической библиотеки, убедитесь, что вы также указали модуль

enter image description here

Это дает вам правильный доступ к сущности MyStaticLibrary.MyManagedObject

Так что, если вы получаете предупреждения с этой точечной нотацией, это не выглядит в вашем модуле