Multithreading CoreData:警告:无法加载名为

Multithreading CoreData:警告:无法加载名为,multithreading,core-data,swift,nsmanagedobject,Multithreading,Core Data,Swift,Nsmanagedobject,我正在使用Xcode 6.1将一个现有的Objective-C电视节目应用程序复制到一个新的Swift版本,我对CoreData有一些问题 我创建了一个包含4个实体的模型,创建了它们的NSManagedObject子类(在Swift中),并且所有文件都设置了正确的应用程序目标(对于“编译源代码”) 每当我尝试插入新实体时,仍会出现此错误: CoreData:警告:无法为实体加载名为“Shows”的类 “表演”。未找到类,改为使用默认NSManagedObject 一些评论: 在保存到核心数据时,

我正在使用Xcode 6.1将一个现有的Objective-C电视节目应用程序复制到一个新的Swift版本,我对CoreData有一些问题

我创建了一个包含4个实体的模型,创建了它们的NSManagedObject子类(在Swift中),并且所有文件都设置了正确的应用程序目标(对于“编译源代码”)

每当我尝试插入新实体时,仍会出现此错误:

CoreData:警告:无法为实体加载名为“Shows”的类 “表演”。未找到类,改为使用默认NSManagedObject

一些评论:

在保存到核心数据时,我使用父子上下文方式来允许后台线程。为此,我使用以下方法设置ManagedObjectContext:

lazy var managedObjectContext: NSManagedObjectContext? = {
  // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
  let coordinator = self.persistentStoreCoordinator
  if coordinator == nil {
    return nil
  }
  var managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.MainQueueConcurrencyType)
  managedObjectContext.persistentStoreCoordinator = coordinator
  return managedObjectContext
}()
并通过以下方式保存数据:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
  var context = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
  context.parentContext = self.managedObjectContext!
  ...rest of core data saving code here...
})

这一警告是我们在解决Swift实施细节时必须解决的问题之一。该警告是错误出现的,即即使您不遵循下面概述的步骤,您的设置也可能正常工作

在大多数情况下,通过确保在模型编辑器中正确设置该类,我可以消除它。与许多其他SOF帖子(包括对这个问题的回答)不同,建议包含模块名称(如
MyApp.Shows
)对我没有帮助

确保检查以下三项:

1.
最高达Xcode 7 beta 3的版本

请注意,我将您的实体名称更正为更合适的单数

适用于Xcode 7.1中Swift 2.0的版本
(应适用于Xcode 7 beta 4及以上版本)

您需要删除模块中的文本“当前产品模块”

2.
您还应该遵循常见的建议,包括

@objc(Show)
就在你班上

注意:如果您使用的是Xcode 7 beta 4或更高版本,此步骤是可选的

3.
还要确保将创建的托管对象强制转换为适当的类,因为默认值仅为
NSManagedObject

var newShow = NSEntityDescription.insertNewObjectForEntityForName("Show", 
                 inManagedObjectContext: context) as Show
SWIFT 2/XCODE 7更新:

这个问题(参见我4月3日对这个答案的评论)在苹果发布的Swift 2和XCode 7测试版中得到了解决。 因此,实际上,您现在不需要像Mundi所回答的那样在Swift中使用
@objc(myEntity)
类名称前的“
MyAppName.
”。它将停止工作。所以删除这些,只需将
名称放入文件中,然后选择
当前工作模块
作为模块 干杯

但是对于那些在Swift中使用
@objc(myEntity)
的人(像我一样),您可以使用另一种解决方案,它可以顺利工作

在xcdatamodel中,请在中更正类。应该是这样的:

    convenience init(<properties to init>) {
    let entityDescr = NSEntityDescription.entityForName("<entity class name>", inManagedObjectContext: <managed context>)
    self.init(entity: entityDescr!, insertIntoManagedObjectContext: <managed context>)}
    //init properties here


给你<代码>模块。类是Swift和XCode 6中CoreData的模式。在模型策略或其他CoreData内容中使用自定义策略类时,也需要相同的过程注意:在图中,名称和类应该是Car和MyAppName.Car(或实体的任何名称)。在这里,
User
是一个输入错误。

在Xcode 6.1.1中,您不需要添加@objc属性,因为基本实体是objc类(NSManagedObject)的子集(请参阅.CoreData中需要完整的模块.Class名称。请注意,模块名称是在“生成设置->打包->产品模块名称”中设置的。默认情况下,该名称设置为$(产品名称:c99extidentifier)这将是目标的名称

不要忘记将
产品模块名称
替换为您的产品模块名称

创建新实体时,您需要转到数据模型检查器(最后一个选项卡)并用您的模块名称替换
PRODUCT\u MODULE\u NAME
,否则在创建持久存储协调器时将导致
类未找到
错误。

您还需要使用(至少在Xcode 6.3.2中)在执行强制转换时使用Module.Class,例如: 假设您的模块(即产品名称)是食品,而您的类是水果

let myEntity =  NSEntityDescription.entityForName("Fruit", inManagedObjectContext: managedContext)

let fruit = NSManagedObject(entity: myEntity!, insertIntoManagedObjectContext:managedContext) as! Food.Fruit
概述:

  • 在数据模型编辑器中定义实体时包括模块名称(名称:Fruit,类:Food.Fruit)
  • 在代码中访问实体(即SWIFT)时,使用Module.class(例如Food.Fruit)将其强制转换

更改数据模型编辑器中的实体类名,使其与所讨论的类相对应,并添加
@objc(NameOfClass)
到类声明正上方的每个NSManagedObject的文件中,为我在单元测试期间解决了这个问题。

当使用Xcode 7和纯Swift时,我实际上必须从自动生成的
NSManagedObject
子类中删除
@objc(MyClass)
(从编辑器>创建NSManagedObject子类生成…。

在Xcode 7 beta 2中(我相信是1),在模型配置中,一个类型为
File
的新托管对象被设置到模块
当前产品模块
,对象的类在配置中显示为
File

删除模块设置使其为空,或删除句号使配置中的类名仅为
文件
是等效的操作,因为每个操作都会导致其他更改。保存此配置将删除所述错误

对我有效的方法(Xcode 7.4,Swift)是将类名更改为
在实体检查器中的“类”框中

托管对象子类的发起人如下所示:

    convenience init(<properties to init>) {
    let entityDescr = NSEntityDescription.entityForName("<entity class name>", inManagedObjectContext: <managed context>)
    self.init(entity: entityDescr!, insertIntoManagedObjectContext: <managed context>)}
    //init properties here
便利初始化(){ 让EntityDescription=NSEntityDescription.entityForName(“,inManagedObjectContext:) self.init(实体:entityDescr!,insertIntoManagedObjectContext:)} //在这里初始化属性
对于xCode 7和Swift 2.0版本,您不需要添加@objc(NameOfClass),只需在“Show”中更改实体设置即可