CoreData:警告:无法加载名为的类

我正在使用Xcode 6.1将现有的Objective-C电视节目应用复制到新的Swift版本,并且遇到了CoreData的一些问题。

我创build了4个实体的模型,创build了它们的NSManagedObject子类(在Swift中),并且所有文件都有适当的应用程序目标设置(对于“编译源”)。

每当我尝试插入一个新的实体时,我仍然遇到这个错误:

CoreData:警告:无法为实体'Shows'加载名为'Shows'的类。 找不到类,使用默认的NSManagedObject来代替。

几点意见:

保存到Core Data时,我使用父子上下文的方式来允许后台线程。 我通过设置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 )的build议对我没有帮助。

确保你检查这三个项目:

1。
Xcode 7 beta 3的版本

最多XCode7 b3

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

在Xcode 7.1中适用于Swift 2.0的版本
(应该适用于Xcode 7 beta 4及更高版本)

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

从Xcode7 beta 3

2。
你也应该按照频繁的build议来包括

 @objc(Show) 

就在你的class级之上。

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

3。
还要确保将创build的托pipe对象转换为适当的类,因为默认情况下只是NSManagedObject

 var newShow = NSEntityDescription.insertNewObjectForEntityForName("Show", inManagedObjectContext: context) as Show 

SWIFT 2 / XCODE 7更新:

这个问题(请参阅我的4月3日对这个答案的评论)在Apple的Swift 2XCode 7testing版发布。 所以,你现在实际上不需要在Swift中使用@objc(myEntity) ,如Mundi所回答的那样,或者在你的Class名字前使用“ MyAppName. ”。 它将停止工作。 所以删除这些,只需将Class名称放在文件中 ,selectCurrent Working Module作为模块,并欢呼!

选择当前的工作模块

但是对于那些在Swift中使用@objc(myEntity)的人(像我一样),你可以使用这个其他的解决scheme,而不是工作顺利。

在xcdatamodel正确的类中。它应该看起来像这样:

设置班级

干得好。 Module.Class是Swift和XCode 6中Module.Class的模式。在Model Policy或其他CoreData的东西中使用Custom Policy类时,也需要相同的过程。 注意:在图像中,名称和类应该是Car和MyAppName.Car(或任何您的实体的名称)。 在这里, User是一个错字。

当使用Xcode 7和纯粹的Swift时,我实际上必须从自动生成的NSManagedObject子类(从Editor > Create NSManagedObject Subclass ...生成@objc(MyClass) 删除 @objc(MyClass) )。

在Xcode 7 beta 2(我相信1)中,在模型configuration中, Filetypes的一个新的托pipe对象被设置为Module Current Product Module ,对象的类在configuration中显示为.File

管理对象类型的模块在Xcode 7中设置为“当前产品模块”

删除模块设置,使其为空白,或删除句号,使configuration中的类名称只是File等效的行为,因为每个导致其他更改。 保存此configuration将删除描述的错误。

被管理对象的模块在Xcode 7中设置为空白

在Xcode 6.1.1中,你不需要添加@objc属性,因为基本实体是一个objc类(NSManagedObject)的一个子集(参见Swifttypes兼容性 ,在CoreData中,完整的Module.Class名是必需的。名称是在“生成设置” – >“打包” – >“产品模块名称”中设置的。默认情况下,它设置为$(PRODUCT_NAME:c99extidentifier),它将是目标的名称

使用xCode 7和Swift 2.0版本,您不需要添加@objc(NameOfClass),只需更改“Show the Data Model Inspector”选项卡中的实体设置(如下所示)

名称 – “您的实体名称”

类 – “您的实体名称”

模块 – “当前产品模块”

在这里输入图像描述

代码为实体类文件将像(在我的代码实体是家庭) –

 import UIKit import CoreData class Family: NSManagedObject { @NSManaged var member : AnyObject } 

这个例子在xCode 7.0 + swift 2.0的应用程序中工作正常

不要忘记用您的产品模块名称replacePRODUCT_MODULE_NAME

当创build一个新实体时,您需要转到数据模型检查器(最后一个选项卡),并将PRODUCT_MODULE_NAMEreplace为您的模块名称,否则在创build持久性存储协调器时将导致class not found错误。

在执行演员时,您还需要使用(至less在Xcode 6.3.2中)Module.Class,例如:假设您的模块(即产品名称)是Food,而您的课程是Fruit

 let myEntity = NSEntityDescription.entityForName("Fruit", inManagedObjectContext: managedContext) let fruit = NSManagedObject(entity: myEntity!, insertIntoManagedObjectContext:managedContext) as! Food.Fruit 

回顾:

  • 在数据模型编辑器(Name:Fruit,Class:Food.Fruit)中定义实体时包含模块名称
  • 当访问代码中的实体(ieSWIFT)时,使用Module.class(例如Food.Fruit)

在数据模型编辑器中更改实体类名称以对应于所讨论的类,并在类声明之上的每个NSManagedObject的文件中添加@objc(NameOfClass)以解决此问题。

我也遇到过类似的问题,请按照以下步骤解决:

  1. 父类是NSManagedObject,而不是NSObject
  2. 实体的模块是默认的,而不是“当前产品模块”

对我来说(Xcode 7.4,Swift),在实体检查器“类”框中将类名更改为<my actual class name>.<entity name>

Managed对象子类的发起者,如下所示:

  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