使用 XCode 7 和 Swift 向下转换的核心数据 NSManagedObject

Posted

技术标签:

【中文标题】使用 XCode 7 和 Swift 向下转换的核心数据 NSManagedObject【英文标题】:Core Data NSManagedObject downcast with XCode 7 and Swift 【发布时间】:2015-07-04 16:30:10 【问题描述】:

在返回行中运行以下代码中止

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 = AppNameWorkout

通过删除 AppName 和 ClassName 之间的点。

那么当我无法在 AppName 和 ClassName 之间设置一个点时,我该如何在 XCode 7 中执行此操作?

【问题讨论】:

为 NSManagedObject 子类和桥接头生成良好的旧 Objective-C 代码会得到相同的结果。 【参考方案1】:

转到您的 cdatamodel..您声明实体的地方..实体下方有一个默认配置。对照您的实体检查 Class 列。默认情况下,这将有一个点前缀。删除点前缀。它应该可以工作。而且据我所知,您不必在 Xcode 7 中使用模块名称作为实体类名称的前缀。因此,您不能在类名称中使用点。我是 ios 开发的新手。所以我可能并不完全正确。但是删除点前缀解决了我在 Xcode 7 中的问题。

【讨论】:

做了一些测试,它在应用程序本身和单元测试目标中对我有用,我在其中导入主应用程序,包括核心数据类。谢谢:-)【参考方案2】:

您需要两个修复: 首先:将您的实体类名称设置为您的实体名称。例如:

Entity name = Entity
Class name = Entity

第二步:在你的实体类文件上面添加这段代码:

@obj(Entity name)

例如:

@obj(Entity)
Class Entity: NSManagedObject  
                   ...

【讨论】:

【参考方案3】:

这些解决方案的组合和您提供的链接让我找到了解决方案,但我花了一段时间才将它们拼凑在一起。这是我想出的(基本上只是一个疏忽):

    单击文件结构/项目中的 .xcdatamodelId 文件 导航器窗格(最左侧)。 选择您遇到问题的实体。 在“实用程序”窗格(最右侧)中,查找看起来像 1997 年手机的图标,即数据模型检查器。 在实体设置下,您应该看到两个字段,“名称”和“类” - 使用您正在使用的类的名称设置“类”(通常与“名称”相同)。

这就是我搞砸的地方,即使我所有的其他实体都有这个设置,我忘记在这个特定的实体上设置这个。在执行这些步骤之前,您甚至会注意到默认的“类”是 NSObject,反映了错误消息。这里的其他一些解决方案可能最终会做同样的事情,但我发现这是最简单/最快的解决方案。

我应该注意,我已经设置了一些其他项目,例如 @objc(Entity) 互操作性参考。

【讨论】:

以上是关于使用 XCode 7 和 Swift 向下转换的核心数据 NSManagedObject的主要内容,如果未能解决你的问题,请参考以下文章

我需要 Xcode 7 和 Swift 2.0 来更新我的应用吗

Swift 2 到 Swift 3 转换 Midi Input

Alamofire 2.0 编译器问题 - Swift 2 / Xcode 7

将多个声音(目标 c)播放到 Swift(xcode 7)的代码帮助

Swift数组不能向下转换为派生数组[重复]

为啥我在 swift 上的视图是这样的 我更新了它,现在我可以向下滑动并能够返回到最后一页 XCODE 11