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

Posted

技术标签:

【中文标题】CoreData:警告:无法加载名为的类【英文标题】:CoreData: warning: Unable to load class named 【发布时间】:2014-10-28 16:51:11 【问题描述】:

我正在使用 Xcode 6.1 将现有的 Objective-C TV Show 应用程序复制到新的 Swift 版本中,但在使用 CoreData 时遇到了一些问题。

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

每当我尝试插入新实体时,我仍然会收到此错误:

CoreData:警告:无法为实体加载名为“Shows”的类 '节目'。找不到类,改用默认的 NSManagedObject。

几个cmets:

当保存到 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...
)

【问题讨论】:

【参考方案1】:

这个警告是我们在解决 Swift 实现的细节时必须处理的怪癖之一。该警告是虚假出现的,即即使您不按照下面概述的步骤进行操作,您的设置也可能有效。

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

请务必检查以下三项:

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

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

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

需要删除Module中的“Current Product Module”文字!

2. 您还应该遵循频繁的建议来包含

@objc(Show)

就在你的班级之上。

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

3. 还要确保将创建的托管对象cast 转换为正确的类,因为默认值为NSManagedObject

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

【讨论】:

谢谢!我确实进行了推荐的命名约定更新,而且似乎是“@objc(Show)”在修复“无法加载类...”错误方面起到了作用。非常感谢! 嗨@Mundi。非常感谢!你还记得源头在哪里吗? 参见例如this question。那里有足够的信息来了解发生了什么。 有趣的是,I had to remove@objc(MyClass) @Mundi,您可能想再次更新您的答案。请参阅 khunshan 的答案更新。【参考方案2】:

SWIFT 2 / XCODE 7 更新:

这个问题(也请参阅我 4 月 3 日对此答案的评论)在 Apple 的 Swift 2XCode 7 测试版中解决 . 所以你现在实际上不需要 Swift 中的@objc(myEntity),正如 Mundi 回答的那样或使用 “MyAppName.”在您的班级名称之前。它将停止工作。所以删除这些,只需将 Class 名称放入 File 并选择 Current Working Module 作为 Module 和欢呼!

但是对于那些在 Swift 中使用 @objc(myEntity) 的人(比如我),你可以使用这个其他的解决方案来代替它,它可以顺利运行。

在xcdatamodel中正确的类中。应该是这样的:

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

【讨论】:

这个解决方案的问题是自动生成实体类将不再正常工作(它只会生成一个具有模块名称的类)。请参阅:Create NSManagedObject subclass not generating properly。 生成NSManagedObject实体类后需要应用该方案。可能是要删除的 xcode 6.xx 错误。 是的,这无疑会得到解决。自动生成的类应该已经用 @objc() 装饰,或者,Apple 更有可能一开始就不需要这样做。 对于仍在阅读本文的人。使用 'MyAppName.Car' 对我不起作用,当我删除 'MyAppName.' 部分时它确实起作用了。所以只需Car 这两个字段就可以了。 你冠军!!!!让 person = NSEntityDescription.insertNewObject(forEntityName: "Person", into: context) as!人【参考方案3】:

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

【讨论】:

哇,感谢您发布此答案。我正要开始用头撞墙。 同样的问题 - 提交了一个错误。 也为我工作。不得不删除它。奇怪。 根据我的实验,这看起来像是误报。 我不得不删除它并设置当前产品模块,然后它才起作用【参考方案4】:

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

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

【讨论】:

【参考方案5】:

在 Xcode 6.1.1 中,您不需要添加 @objc 属性,因为基本实体是 objc 类 (NSManagedObject) 的子集(请参阅 Swift Type Compatibility。在 CoreData 中,完整的 Module.Class 名称是必需的。是注意模块名称是在 Build Settings -> Packaging -> Product Module Name 中设置的。默认设置为 $(PRODUCT_NAME:c99extidentifier),这将是 Target 的名称

【讨论】:

是的!这是现代答案(xcode 6.3.2)。使用正确的捆绑名称是关键。就我而言,它已将my-product 转换为my_product,这对Core Data 产生了影响。【参考方案6】:

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

名称 - “您的实体名称”

类 - “您的实体名称”

模块 - “当前产品模块”

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

import UIKit
import CoreData

class Family: NSManagedObject 

   @NSManaged var member : AnyObject

这个例子在我的 xCode 7.0 + swift 2.0 应用中运行良好

【讨论】:

【参考方案7】:

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

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

【讨论】:

【参考方案8】:

在执行强制转换时,您还需要使用(至少在 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”。【参考方案9】:

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

    The parent is NSManagedObject, not NSObject The module of an entity is default, not "Current Product Module"

【讨论】:

【参考方案10】:

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

【讨论】:

【参考方案11】:

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

我的托管对象子类的发起者,如下所示:

    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

【讨论】:

【参考方案12】:

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

【讨论】:

以上是关于CoreData:警告:无法加载名为的类的主要内容,如果未能解决你的问题,请参考以下文章

Swift 4,CoreData:错误:无法加载名为 textTabelView 的模型

无法为实体“位置”加载名为“MyLocations.Location”的类

Swift 3 获取请求错误(警告:无法加载任何 Objective-C 类信息)

CoreData 崩溃

无法从线程上下文、当前或系统/应用程序加载名为 [io.jsonwebtoken.io.JacksonSerializer] 的类

iOS Today Extension - 共享核心数据