无法找到NSManagedObject的特定子类

时间:2014-08-01 08:47:59

标签: ios core-data swift nsmanagedobject

我正在开发使用Core Data的应用程序。当我使用:

创建实例时
let entity = NSEntityDescription.entityForName("User", inManagedObjectContext: appDelegate.managedObjectContext)
let user = User(entity: entity, insertIntoManagedObjectContext: appDelegate.managedObjectContext)

我在日志中收到警告:

CoreData: warning: Unable to load class named 'User' for entity 'User'.  Class not found, using default NSManagedObject instead.

我该如何解决?

另一个问题是,如何在NSManagedObject子类中定义实例方法?

编辑:

我已指定实体的类,如以下屏幕截图所示:

enter image description here

13 个答案:

答案 0 :(得分:215)

Xcode 7更新(最终版): 不再需要将模块名称添加到类中(如Xcode 6和Xcode 7的早期beta版本)。 Apple文档Implementing Core Data Managed Object Subclasses已经存在 相应更新。

数据模型检查器 现在有一个实体的两个字段“Class”和“Module”:

enter image description here

当您为实体创建Swift托管对象子类时, “模块”字段设置为“当前产品模块”,并使用此设置 创建实例在主应用程序和单元测试中都有效。 托管对象子类必须标记为@objc(classname)(在https://stackoverflow.com/a/31288029/1187415中观察到这一点)。

或者,可以清空“模块”字段(它将显示“无”)并标记 使用@objc(classname)的托管对象子类(观察到了这一点) 在https://stackoverflow.com/a/31287260/1187415)。


备注:这个答案最初是为Xcode 6编写的。 各种Xcode 7 beta版本都有一些变化 尊重这个问题。因为它是许多人接受的答案 upvotes和链接,我试图总结一下情况 对于当前的Xcode 7最终版本。

我做了我自己的“研究”并阅读了这个问题和类似问题的所有答案 CoreData: warning: Unable to load class named。因此归属于所有人,即使我不这样做 专门列出它们!


Xcode 6 的上一个答案:

Implementing Core Data Managed Object Subclasses中所述,您必须这样做 使用模块名称在模型实体检查器的“类”字段中为实体类名添加前缀,例如“MyFirstSwiftApp.User”。

答案 1 :(得分:60)

就像旁注一样。我遇到过同样的问题。我所要做的就是在我的类文件中添加@objc(ClassName)

示例:

@objc(Person)
class Person { }

这解决了我的问题。

答案 2 :(得分:30)

这个问题的接受答案帮助我解决了同样的问题,但我有一个警告,我认为这对其他人有帮助。如果项目(模块)名称中有空格,则必须用下划线替换空格。例如:

实体:MyEntity 类:My_App_Name.MyClass

答案 3 :(得分:16)

请务必删除模块

enter image description here

答案 4 :(得分:9)

如果您作为应用与测试运行,则问题可能是应用正在寻找<appName>.<entityName>,当它作为测试运行时,它看起来像<appName>Tests.<entityName>。我此时使用的解决方案(Xcode 6.1)是不填充CoreData UI中的Class字段,而是在代码中填写。

此代码将检测您是否作为App vs Tests运行,并使用正确的模块名称并更新managedObjectClassName

lazy var managedObjectModel: NSManagedObjectModel = {
    // The managed object model for the application. This property is not optional...
    let modelURL = NSBundle.mainBundle().URLForResource("Streak", withExtension: "momd")!
    let managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)!

    // Check if we are running as test or not
    let environment = NSProcessInfo.processInfo().environment as [String : AnyObject]
    let isTest = (environment["XCInjectBundle"] as? String)?.pathExtension == "xctest"

    // Create the module name
    let moduleName = (isTest) ? "StreakTests" : "Streak"

    // Create a new managed object model with updated entity class names
    var newEntities = [] as [NSEntityDescription]
    for (_, entity) in enumerate(managedObjectModel.entities) {
        let newEntity = entity.copy() as NSEntityDescription
        newEntity.managedObjectClassName = "\(moduleName).\(entity.name)"
        newEntities.append(newEntity)
    }
    let newManagedObjectModel = NSManagedObjectModel()
    newManagedObjectModel.entities = newEntities

    return newManagedObjectModel
}()

答案 5 :(得分:8)

如果您在项目名称中使用连字符,例如“My-App”,则使用下划线而不是连字符,如“My_App.MyManagedObject”。 通常,查看xcdatamodeld文件的名称并使用与该名称相同的前缀。 即“My_App_1.xcdatamodeld”需要前缀“My_App_1”

答案 6 :(得分:5)

这可能会帮助那些遇到同样问题的人。我是,使用Swift 2和Xcode 7 beta 2。

在我的案例中,

The solution是在@objc(EntityName)中评论EntityName.swift

答案 7 :(得分:3)

我有同样的警告,虽然我的应用似乎运行良好。 问题是当运行Editor&gt;在我使用默认组位置的最后一个屏幕上创建NSManagedObject子类,没有显示或选中目标,这将子类保存在MyApp.xcodeproj所在的顶部MyApp目录中。
当我改为将组更改为MyApp子文件夹并检查MyApp目标时,警告就消失了。

答案 8 :(得分:2)

顺便说一下,你添加什么作为前缀:我的应用程序被称为“ABC-def”,Xcode将“ - ”转换为“_”。

为了安全查看查找程序,找到您的项目文件并查看它对您的数据模型所说的内容(例如“ABC_def.xcdatamodeld”)并使用那里写的内容!

答案 9 :(得分:1)

上述答案很有帮助。这种快速的健全检查可以为您节省一些时间。进入项目&gt;构建阶段&gt;编译源并使用&#34; - &#34;删除xcdatamodeld和模型文件。按钮,然后使用&#34; +&#34;将它们添加回来按钮。重建 - 可以照顾它。

答案 10 :(得分:1)

上述答案帮助我解决了与Objective-C相关的不同问题(也许会对某人有所帮助):

如果您重构了实体名称,请不要忘记更改&#34; Class&#34;在&#34;公用事业面板&#34;同样。

答案 11 :(得分:0)

以上答案对我有所帮助,但这对某些人有帮助。如果像我一样你做了它们并且仍然有问题,记得简单地“清理你的项目”。对于XCode8,产品&gt;清洁。然后又跑了。

答案 12 :(得分:0)

在Xcode 7中,实体和类名称可以相同,但Codegen应该是类定义。在这种情况下,将没有警告等。enter image description here