无法找到 NSManagedObject 的特定子类

我正在开发一个核心数据应用程序,当我创建了一个实例,使用:

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

39556 次浏览

Xcode 7(最终版)的更新: 不再需要将模块名称添加到类中(如 Xcode 6和 Xcode 7的早期 beta 版本)。 苹果的文档 实现核心数据管理对象子类已经 相应更新。

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

enter image description here

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

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


备注: 这个答案最初是为 Xcode 6编写的。 在 Xcode 7 beta 版本中有一些变化 因为这是一个被许多人接受的答案 我已经试图总结情况 对于当前的 Xcode 7最终版本。

我做了自己的“研究”,并阅读了这个问题和类似问题的所有答案 CoreData: 警告: 无法加载名为 的类。因此,即使我没有加载,属性也会归于所有类 具体列出来!


Xcode 6的上一个答案:

正如 实现核心数据管理对象子类中记录的那样,你必须 在模型实体检查器的 Class 字段中,为实体类名称加上模块名称的前缀,例如“ MyFirstSwiftApp”。用户」。

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

实体: 我的实体 类: My _ App _ Name. MyClass

只是个小插曲。我也有同样的问题。我所要做的就是在我的类文件中加入 @objc(ClassName)

例如:

@objc(Person)
class Person { }

这就解决了我的问题。

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

此代码将检测您是否正在运行应用程序与测试,并使用正确的模块名称和更新 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
}()

如果您在项目名称中使用连字符,比如“ My-App”,那么使用下划线代替“ My _ App”这样的连字符。MyManagedObject”。 通常,查看 xcdatamodeld 文件的名称并使用与该名称相同的前缀。 例如,“ My _ App _ 1. xcdatamodeld”需要前缀“ My _ App _ 1”

以上的回答很有帮助。这个快速的健康检查可以为您节省一些时间。进入项目 > 构建阶段 > 编译源,用“-”按钮删除 xcdatamodeld 和模型文件,然后用“ +”按钮将它们直接添加回去。重建,也许能解决问题。

上面的答案帮助我解决了与 Objective-C 相关的不同问题(也许它能帮到某人) :

如果您重构了实体名称,不要忘记在“实用程序面板”中更改“类”。

我也收到了同样的警告,尽管我的应用程序似乎运行良好。 问题是,在最后一个屏幕上运行 Editor > Create NSManagedObject Subclass 时,我使用了默认的 Group 位置,没有显示或选中 Targets,这将子类保存在 MyApp.xcodeproj 所在的 MyApp 顶部目录中。
当我将 Group 更改为 MyApp 子文件夹并选中 MyApp 目标时,警告消失了。

顺便说一下,小心添加前缀: My App 被称为“ ABC-def”,Xcode 已经将“-”转换为“ _”。

为了安全起见,查找查找程序,找到您的项目文件,看看它对您的数据模型说了什么(例如“ ABC _ def。“ xcdatamodeld”) ,并使用写在那里的正确! ! !

记得移除你的 模组:

enter image description here

这可能会帮助那些遇到同样问题的人。

在我的例子中,解决方案 是在 EntityName.swift中注释掉 @objc(EntityName)

以上的答案对我有帮助,但这个答案可能对某些人有帮助。如果你像我一样做了,但仍然有问题,记得简单地“清理你的项目”。对于 XCode8,Product > Clean。那就再跑一次。

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

enter image description here