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

时间:2014-10-28 16:51:12

标签: multithreading core-data swift nsmanagedobject

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

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

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

  

CoreData:警告:无法加载名为'显示'对于实体   '节目&#39 ;.找不到类,而是使用默认的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...
})

12 个答案:

答案 0 :(得分:169)

这个警告是我们必须处理的一个怪癖,而Swift实施的细节正在被解决。该警告是虚假发生的,即即使您不遵循下面列出的步骤,您的设置也可能有效。

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

请务必检查以下三项:

<强> 1
适用于Xcode 7 beta 3的版本

Up to XCode7 b3

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

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

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

From Xcode7 beta 3

<强> 2
您还应遵循频繁的建议,包括

@objc(Show)

就在你的班级之上。

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

第3
还要确保强制创建的托管对象到正确的类,因为默认值只有NSManagedObject

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

答案 1 :(得分:66)

  

SWIFT 2 / XCODE 7更新:

     

此问题(请参阅我在4月3日对此答案的评论)在Apple的 Swift 2 XCode 7 测试版中已解决 。   所以你实际上现在不需要在Swift中使用@objc(myEntity)作为Mundi或使用的答案   &#34; MyAppName.&#34;在你的班级名称之前。它会停止工作。所以删除这些,只需将Class名称放在文件中,然后选择Current Working Module作为模块   和欢呼!

     

Selecting current working module

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

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

Setting the class

你走了。 Module.Class 是Swift和XCode 6中CoreData的模式。在模型策略或其他CoreData内容中使用自定义策略类时,您还需要相同的过程。 注意:在图片中,名称和类应为Car和MyAppName.Car(或您实体的任何名称)。在这里,User是一个错字。

答案 2 :(得分:36)

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

答案 3 :(得分:12)

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

Module of managed object type set to "Current Product Module" in Xcode 7

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

Module of managed object set to be blank in Xcode 7

答案 4 :(得分:9)

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

答案 5 :(得分:5)

使用xCode 7和Swift 2.0版本,您不需要添加@objc(NameOfClass),只需在&#34;显示数据模型检查器&#34;中更改实体设置。标签如下 -

姓名 - &#34;您的实体名称&#34;

班级 - &#34;您的实体名称&#34;

模块 - &#34;当前产品模块&#34;

enter image description here

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

import UIKit
import CoreData

class Family: NSManagedObject {

   @NSManaged var member : AnyObject
}

此示例在我的应用程序中使用xCode 7.0 + swift 2.0

正常工作

答案 6 :(得分:3)

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

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

答案 7 :(得分:2)

You also need to use (at least with Xcode 6.3.2) Module.Class when performing your cast for example: Assuming your module (i.e. product name) is Food and your class is Fruit

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

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

Recap:

  • Include module name when defining entity in Data Model Editor (Name: Fruit, Class: Food.Fruit)
  • When accessing the entity in code (i.e.SWIFT), cast it with Module.class (e.g. Food.Fruit)

答案 8 :(得分:1)

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

答案 9 :(得分:1)

答案 10 :(得分:0)

对我有用的东西(Xcode 7.4,Swift)正在将类名更改为<my actual class name>.<entity name> 在实体检查员中,&#39; Class&#39;框。

我的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

答案 11 :(得分:0)

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