首页 文章

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

提问于
浏览
82

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

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

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

CoreData:警告:无法为实体“显示”加载名为“显示”的类 . 找不到类,而是使用默认的NSManagedObject .

A few comments:

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

11 回答

  • 9

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

    在大多数情况下,我已经能够摆脱它 by making sure that the class is set correctly in the model editor . 与许多其他SOF帖子(包括此问题的答案)不同,包含模块名称(如 MyApp.Shows )的建议已经帮助了我 .

    请务必检查以下三项:

    1.
    Version that works up to Xcode 7 beta 3

    Up to XCode7 b3

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

    Version that works for Swift 2.0 in Xcode 7.1 (Should work for Xcode 7 beta 4 and above)

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

    From Xcode7 beta 3

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

    @objc(Show)
    

    就在你的 class 之上 .

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

    3.
    还要确保 cast 创建的托管对象到正确的类,因为默认情况下只是 NSManagedObject .

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

    SWIFT 2 / XCODE 7更新:此问题(请参阅我在4月3日对此答案的评论)在Apple的Swift 2和XCode 7测试版中得到解决 . 所以你实际上现在不需要在Swift中使用@objc(myEntity)作为Mundi或使用“MyAppName”的回答 . 在你的 class 名称之前 . 它会停止工作 . 所以删除这些,只需将类名放在文件中,然后选择当前工作模块作为模块和欢呼!

    但是对于那些在Swift中使用 @objc(myEntity) 的人(和我一样),你可以使用其他解决方案,它可以顺利运行 .

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

    Setting the class

    干得好 . Module.Class 是Swift和XCode 6中CoreData的模式 . 在模型策略或其他CoreData内容中使用自定义策略类时,您还需要相同的过程 . A note: In image, The Name and Class should be Car and MyAppName.Car (or whatever the name of your entity). Here, User is a typo.

  • 5

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

  • 35

    在Xcode 7 beta 2(我相信1)中,在模型配置中,类型为 File 的新托管对象设置为Module 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

  • 1

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

  • 2

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

    名称 - “您的实体名称”

    类 - “您的实体名称”

    模块 - “当前产品模块”

    enter image description here

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

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

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

  • 162

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

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

  • 0

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

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

    概括:

    • 在数据模型编辑器中定义实体时包含模块名称(名称:Fruit,Class:Food.Fruit)

    • 在代码中访问实体时(即.SWIFT),使用Module.class(例如Food.Fruit)进行投射

  • 1

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

  • 11
  • 2

    对我有用的东西(Xcode 7.4,Swift)正在实体检查器'Class'框中将类名更改为 <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
    

相关问题