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


94

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

我创建了一个包含4个实体的模型,创建了它们的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...
})

Answers:


177

在解决Swift实现的细节时,此警告是我们必须处理的怪癖之一。该警告是虚假的,即,即使您不遵循以下概述的步骤,您的设置也可能会起作用。

在大多数情况下,通过确保在模型编辑器中正确设置了类,我可以摆脱它。不像许多其他的SOF职位(包括这个问题的答案),建议以包括模块名称(如MyApp.Shows)有没有我帮助。

确保检查以下三个项目:

1.
适用于Xcode 7 beta 3的版本

最高XCode7 b3

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

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

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

从Xcode7 beta 3开始

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

@objc(Show)

就在你班上

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

3.
还要确保所创建的管理对象到适当的类,作为默认的将只是NSManagedObject

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

3
谢谢!我确实进行了推荐的命名约定更新,而似乎是@@ objc(Show)似乎可以解决“无法加载类...”错误。非常感激!
JimmyJammed 2014年

嗨@Mundi 非常感谢!您还记得来源在哪里吗?
iamdavidlam 2014年

1
参见例如这个问题。那里有足够的信息来了解正在发生的事情。
芒迪2014年

4
有趣的是,我不得不删除 @objc(MyClass)
圣诞老人

1
@Mundi,您可能想再次更新您的答案。请参阅khunshan的答案更新。
Suragch

75

SWIFT 2 / XCODE 7更新:

苹果公司在Swift 2XCode 7 beta版本中解决了此问题(也请参见4月3日对此答案的评论)。因此,您实际上实际上不需要在Swift中由Mundi回答,也不需要在班级名称前使用“ ”。它将停止工作。因此删除这些,只需在文件中输入名称,然后选择“ 模块”即可@objc(myEntity)MyAppName.ClassCurrent Working Module

选择当前的工作模块

但是对于那些@objc(myEntity)在Swift中使用的人(像我一样),您可以改用其他解决方案,该方案可以正常运行。

在xcdatamodel中正确的类中。它应如下所示:

设置课程

干得好。Module.Class是Swift和XCode 6中CoreData的模式。在模型策略或其他CoreData中使用自定义策略类时,您还将需要相同的过程。 注意:在图像中,“名称和类”应该是Car和MyAppName.Car(或您实体的任何名称)。这User是一个错字。


该解决方案的问题在于,自动生成实体类将无法再正常工作(它将仅生成具有模块名称的一个类)。请参阅:创建NSManagedObject子类无法正确生成
米洛斯2015年

您需要在生成NSManagedObject实体类之后应用解决方案。可能是要删除的xcode 6.xx错误。
khunshan 2015年

2
是的,这无疑将得到解决。自动生成的类应该已经用@objc(<在实体检查器中输入的类名称>)进行了修饰,或者更有可能的是,Apple将使这不必要。
米洛斯2015年

2
对于仍在阅读此书的人。使用' MyAppName.Car '不适用于我,当我删除' MyAppName时,它确实起作用'部分。因此,仅Car针对这两个领域就可以了。
基甸2015年

1
你冠军!!让person = NSEntityDescription.insertNewObject(forEntityName:“ Person”,into:context)为!人
Abhimanyu Rathore

36

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


4
哇,谢谢你发布这个答案。我正要开始撞墙。
Zia

此处存在相同问题-提交了错误。
MirekE

也为我工作。不得不将其删除。奇怪
肯特,2015年

根据我的实验,它看起来像是假阳性。
Mundi

我必须删除它并设置“当前产品模块”,然后它才起作用
Oleg Sherman '18

13

在Xcode 7 beta 2(我相信1)中,在模型配置中,将新的托管对象类型File设置为Module,Current Product Module并且该对象的类在配置中显示为.File

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

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

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


9

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


是! 这是现代的答案(xcode 6.3.2)。使用正确的捆绑包名称是关键。就我而言,它已转换my-productmy_product,这对Core Data产生了很大的影响。
SimplGy 2015年

5

对于xCode 7和Swift 2.0版本,您无需添加@objc(NameOfClass),只需在“显示数据模型检查器”选项卡中更改实体设置,如下所示-

名称-“您的实体名称”

类-“您的实体名称”

模块-“当前产品模块”

在此处输入图片说明

实体类文件的代码将类似于(在我的代码中,实体为家庭)-

import UIKit
import CoreData

class Family: NSManagedObject {

   @NSManaged var member : AnyObject
}

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


3

不要忘记PRODUCT_MODULE_NAME用产品模块名称替换。

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


2

例如,执行演员表转换时,您还需要使用(至少与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

回顾:

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

谢谢,第二点很重要。强制转换时必须使用“ Module.Class”。
Zoyt 2015年


1

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


0

对我有用的(Xcode 7.4,Swift)是<my actual class name>.<entity name> 在Entity inspector的“ Class”框中将类名更改为。

我的托管对象子类的启动器如下所示:

    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

0

对于Xcode 11.5:如果Codegen属性是class Definition,并且没有获得关于在xcdatamodel中创建的实体的建议。尝试退出Xcode并再次重新打开您的项目。这个对我有用。仅当您没有收到建议但没有生成文件时,才尝试上述任何答案。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.