核心数据 NSManagedObject 向下转换 XCode 7 和 Swift
Core Data NSManagedObject downcast with XCode 7 and Swift
运行 以下代码在 return 行
中止
Type is not Workout
Could not cast value of type
'NSManagedObject_Workout_' (0x7fcca20620f0) to
'AppName.Workout' (0x100ea5f40)).
if let...里面的部分永远不会执行。
func createWorkoutWithName (name: String) -> Workout? {
let entityName = NSStringFromClass(Workout.classForCoder())
let newEntity = NSEntityDescription.insertNewObjectForEntityForName(entityName, inManagedObjectContext: managedObjectContext)
if let newEntity = newEntity as? Workout {
newEntity.name = name
}
NSLog("createWorkoutWithName: Type is not Workout")
return (newEntity as! Workout)
}
我过去遇到过这个问题,我在 XCode 6.x 中解决了它,方法是进入实体检查器并设置 Class = AppName.Workout
建议此解决方案的几个答案之一是
How come I can cast to NSManagedObject but not to my entity's type?
XCode 7 为这个问题添加了一个新的转折点:
当我设置
Class = AppName.Workout
在实体检查器中,XCode 7 自动将 class 名称更改为
Class = AppNameWorkout
删除 AppName 和 ClassName 之间的点。
当我无法在 AppName 和 ClassName 之间设置一个点时,我该如何在 XCode 7 中执行此操作?
转到您的 cdatamodel..您声明实体的位置..实体下方有一个默认配置。根据您的实体检查 Class 列。默认情况下,这将有一个点前缀。删除点前缀。它应该可以工作。据我所知,您不必在实体 class 名称前加上 Xcode 7 中的模块名称。因此,您不能在 class name.I 中使用点我是 iOS 开发的新手。所以我可能不完全正确。但是删除点前缀解决了我在 Xcode 7.
中的问题
您需要两个修复程序:
第一:将您的实体 class 名称设置为您的实体名称。例如:
Entity name = Entity
Class name = Entity
其次:将此代码添加到您的实体 class 文件上方:
@obj(Entity name)
例如:
@obj(Entity)
Class Entity: NSManagedObject {
...
}
这些解决方案与您提供的 link 的组合使我找到了解决方案,但我花了一些时间才将它们拼凑在一起。这是我想出的(基本上只是一个疏忽):
- 单击文件中的 .xcdatamodelId 文件 structure/project
导航器窗格(最左侧)。
- Select 您遇到问题的实体。
- 在“实用程序”窗格(最右侧)中,查找看起来像 1997 年单元格的图标 phone,数据模型检查器。
- 在实体设置下,您应该看到两个字段,"Name" 和 "Class" - 使用您正在使用的 class 的名称设置 "Class"(通常与 "Name").
相同
这就是我搞砸的地方,即使我的所有其他实体都有这个设置,我忘记在这个特定实体上设置它。在执行这些步骤之前,您甚至会注意到默认的 "class" 是 NSObject,反映了错误消息。这里的其他一些解决方案可能最终会做同样的事情,但我发现这是 simplest/quickest 解决方案。
我应该注意,我已经设置了一些其他项目,例如 @objc(Entity) 互操作性参考。
运行 以下代码在 return 行
中止Type is not Workout
Could not cast value of type
'NSManagedObject_Workout_' (0x7fcca20620f0) to
'AppName.Workout' (0x100ea5f40)).
if let...里面的部分永远不会执行。
func createWorkoutWithName (name: String) -> Workout? {
let entityName = NSStringFromClass(Workout.classForCoder())
let newEntity = NSEntityDescription.insertNewObjectForEntityForName(entityName, inManagedObjectContext: managedObjectContext)
if let newEntity = newEntity as? Workout {
newEntity.name = name
}
NSLog("createWorkoutWithName: Type is not Workout")
return (newEntity as! Workout)
}
我过去遇到过这个问题,我在 XCode 6.x 中解决了它,方法是进入实体检查器并设置 Class = AppName.Workout
建议此解决方案的几个答案之一是 How come I can cast to NSManagedObject but not to my entity's type?
XCode 7 为这个问题添加了一个新的转折点: 当我设置
Class = AppName.Workout
在实体检查器中,XCode 7 自动将 class 名称更改为
Class = AppNameWorkout
删除 AppName 和 ClassName 之间的点。
当我无法在 AppName 和 ClassName 之间设置一个点时,我该如何在 XCode 7 中执行此操作?
转到您的 cdatamodel..您声明实体的位置..实体下方有一个默认配置。根据您的实体检查 Class 列。默认情况下,这将有一个点前缀。删除点前缀。它应该可以工作。据我所知,您不必在实体 class 名称前加上 Xcode 7 中的模块名称。因此,您不能在 class name.I 中使用点我是 iOS 开发的新手。所以我可能不完全正确。但是删除点前缀解决了我在 Xcode 7.
中的问题您需要两个修复程序: 第一:将您的实体 class 名称设置为您的实体名称。例如:
Entity name = Entity
Class name = Entity
其次:将此代码添加到您的实体 class 文件上方:
@obj(Entity name)
例如:
@obj(Entity)
Class Entity: NSManagedObject {
...
}
这些解决方案与您提供的 link 的组合使我找到了解决方案,但我花了一些时间才将它们拼凑在一起。这是我想出的(基本上只是一个疏忽):
- 单击文件中的 .xcdatamodelId 文件 structure/project 导航器窗格(最左侧)。
- Select 您遇到问题的实体。
- 在“实用程序”窗格(最右侧)中,查找看起来像 1997 年单元格的图标 phone,数据模型检查器。
- 在实体设置下,您应该看到两个字段,"Name" 和 "Class" - 使用您正在使用的 class 的名称设置 "Class"(通常与 "Name"). 相同
这就是我搞砸的地方,即使我的所有其他实体都有这个设置,我忘记在这个特定实体上设置它。在执行这些步骤之前,您甚至会注意到默认的 "class" 是 NSObject,反映了错误消息。这里的其他一些解决方案可能最终会做同样的事情,但我发现这是 simplest/quickest 解决方案。
我应该注意,我已经设置了一些其他项目,例如 @objc(Entity) 互操作性参考。