Ответ 1
Проблема заключалась в том, что я не проверил Class Module: текущий модуль продукта для CDWorkout Entity.
Я создал простую сущность '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.
Чего я забыл?
Проблема заключалась в том, что я не проверил Class Module: текущий модуль продукта для CDWorkout Entity.
В моем случае такая же проблема была в модификаторе @objc в автоматически сгенерированном заголовке класса данных.
@objc(CachedMovie)
public class CachedMovie: NSManagedObject {
Я только что удалил @objc(CachedMovie)
и он начал работать
У меня была глупая незначительная проблема, которая привела к той же ошибке. Я инициализировал NSPersistentContainer с неправильным именем.
Он должен иметь то же имя, что и исходный файл с расширением .xcdatamodeld. например modelFileName.xcdatamodelId
let persistentContainer = NSPersistentContainer(name: "modelFileName")
Я столкнулся с этим же сообщением об ошибке при попытке вставить/добавить управляемый объект из расширения (SiriKit). Похоже, что проблема с пространством имен расширения не соответствует файлу .xcdatamodeld
, потому что я создавал описание сущности с помощью MyClass.entity()
.
Сочетание, которое сработало для меня, было:
@objc(MyClass)
в верхней части каждого подкласса NSManagedObject
let entity = NSEntityDescription.entity(forEntityName: "MyClass", in: context)!
в вашем файле modeldataClass, вероятно, имя класса неверно, прежде чем вы измените имя в классе имени
Вам нужно создать новый NSManagedObject
, прежде чем вы сможете его использовать
let workout = NSEntityDescription.insertNewObjectForEntityForName("CDWorkout",
inManagedObjectContext: context) as! CDWorkout
теперь вы можете установить имя так же, как и вы: workout.name = "any_name"
вы можете обратиться к Документация CoreData для получения дополнительной информации о CoreDatap >
У меня была аналогичная проблема в стеке 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
}
}
Я пытался добавить CoreData в существующий проект, и я много переименовал вещи. Я закончил с несколькими .xcdatamodeld, не зная об этом. Решением было удаление .xcdatamodeld, создание NSManagerObject и повторное его создание.
легко ответить на этот вопрос. без удаления
@objc(Workout)
решение заключается в документальном программировании базовых данных " имя объекта и имя класса ". здесь, в вашем XCode, прежде чем делать (Editor → Create 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
}
}
Ошибка, которую я сделал, состояла в том, чтобы изменить имя сущности и сгенерированный "NSManagedObject Subclass", а не обновить имя класса. Как исправить:
Если вы используете coreData из статической библиотеки, убедитесь, что вы также указали модуль
Это дает вам правильный доступ к сущности MyStaticLibrary.MyManagedObject
Так что, если вы получаете предупреждения с этой точечной нотацией, это не выглядит в вашем модуле