我创建了简单的实体' CDWorkout'有一个属性' name'在CDModel.xcdatamodeld中。 AppDelegate中容器的名称也是“CDModel'”。用于' CDWorkout'的类Codegen是类别/扩展。这是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',原因:'类的' Workout_Generator.CDWorkout'的NSManagedObject必须有一个有效的NSEntityDescription。'
我忘记了什么?
答案 0 :(得分:16)
问题是我没有检查类模块:CDWorkout Entity的当前产品模块。
答案 1 :(得分:8)
在我的情况下,同样的问题出现在自动生成的数据类头中的@objc修饰符
@objc(CachedMovie)
public class CachedMovie: NSManagedObject {
我刚刚删除@objc(CachedMovie)
并开始工作
答案 2 :(得分:6)
我有一个愚蠢的小问题,导致同样的错误。我用不正确的名称初始化NSPersistentContainer。
它应与源文件的名称相同,扩展名为 .xcdatamodeld 。例如 modelFileName.xcdatamodelId
let persistentContainer = NSPersistentContainer(name: "modelFileName")
答案 3 :(得分:4)
尝试从扩展程序(SiriKit)插入/添加托管对象时,我遇到了同样的错误消息。这似乎是扩展名称空间与.xcdatamodeld
文件不匹配的问题,因为我使用MyClass.entity()
创建了实体描述。
对我有用的组合是:
@objc(MyClass)
位于每个NSManagedObject
子类let entity = NSEntityDescription.entity(forEntityName: "MyClass", in: context)!
答案 4 :(得分:3)
发生这种情况的一种方法是尝试重命名您的实体。确保这些相同!
答案 5 :(得分:1)
我遇到了同样的问题。就我而言,我使用了在框架中初始化和管理的 CoreData,我通过 SPM 与主应用程序集成。
首先,在框架中手动为实体提供模块名称,步骤如下:
对每个实体重复这些步骤。
其次,在框架中为您在项目中使用的每个 NSManagedObject 覆盖 description
,f.ex。你有:
public class Person: NSManagedObject {
}
使用没有模块名称的字符串覆盖那里的描述,例如:
public class Person: NSManagedObject {
public override var description: String {
return "Person"
}
}
如果您对使用 Person(context: Context)
指定 description
的 Person 使用便利初始化程序(如 Person.entity()
),上述代码将有所帮助。
答案 6 :(得分:1)
我在使用 Swift 包管理器导入一个包含模型文件作为资源的 Swift 包时遇到了这个问题。在我的情况下,将实体的模块设置为 Current Production Module
在模型文件中产生了不正确的值。当我在加载持久性容器后使用调试器打印模型时,完全限定的类名类似于 Module_Module.Class
而不是预期的 Module.Class
。我不得不手动输入模块名称而不是使用 Current Production Module
来解决问题。
答案 7 :(得分:1)
对我来说,我忘记在下面的例子中添加@objc(Reminder)。我以编程方式编写了 NSManagedObject 类。
@objc(Reminder)
public class Reminder: NSManagedObject {
}
答案 8 :(得分:1)
如果您要使用静态库中的coreData,请确保同时指定模块
这为您提供了正确的实体访问权限MyStaticLibrary.MyManagedObject
因此,如果您收到带有该点符号的警告,则表示它不在您的模块中
答案 9 :(得分:1)
答案 10 :(得分:0)
我犯的错误是更改实体名称和生成的“ NSManagedObject子类”,而不更新类的名称。解决方法:
答案 11 :(得分:0)
很容易回答这个问题。未被删除
@objc(Workout)
解决方案位于“ 实体名称和类名称”上的纪录片Core Data Programming上。 在执行此操作之前,在Xcode中点击此处(编辑器-> 创建NSManagedObject子类) 必须更改您的实体类名称以添加“ 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
}
}
答案 12 :(得分:0)
在AppDelegate中检查持久性容器名称。 let container = NSPersistentContainer(name:“ CoreData”)
如果您尝试获取不存在的核心数据,则可能显示为此错误。
名称应与导航菜单中的.xcdatamodeld对象完全相同。
GL:)
答案 13 :(得分:0)
对于SwiftUI,您还需要从SceneDelegate更新此方法:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
//This gets the context from AppDelegate and sets is as moc environment variable
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let contentView = ContentView().environment(\.managedObjectContext, context)
//...
}
答案 14 :(得分:0)
我正在尝试将CoreData添加到现有项目中,并且我重命名了很多东西。我最终得到了多个.xcdatamodeld而不知道它。解决方案是删除.xcdatamodeld并生成NSManagerObject并重新创建它。
答案 15 :(得分:0)
我在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
}
}
答案 16 :(得分:0)
您需要先创建新的NSManagedObject
才能使用它
let workout = NSEntityDescription.insertNewObjectForEntityForName("CDWorkout",
inManagedObjectContext: context) as! CDWorkout
现在您可以像以前一样设置名称:workout.name = "any_name"
您可以参考CoreData Documentation了解有关CoreData的更多信息