【问题标题】:How come I can cast to NSManagedObject but not to my entity's type?为什么我可以转换为 NSManagedObject 但不能转换为我的实体类型?
【发布时间】:2014-07-31 23:46:45
【问题描述】:

我在一个新项目中使用了 Core Data 的 Swift 样板代码。我的 .xcdatamodeld 文件定义了一个实体 (Task) 和一个属性 (name)。

我有一个如下所示的Task.swift 文件:

import CoreData

class Task: NSManagedObject {
    @NSManaged var name: String
}

当我运行它时,它可以工作:

var firstTask = NSEntityDescription.insertNewObjectForEntityForName("Task",
    inManagedObjectContext: managedObjectContext) as NSManagedObject

firstTask.setPrimitiveValue("File my TPS reports", forKey: "name")

var error: NSError?

managedObjectContext.save(&error)

我什至可以进入 iOS 模拟器使用的 SQLite 数据库并确认该行已添加。

但是,当我运行与上面完全相同的代码但使用as Task 而不是as NSManagedObject 时,我会遇到与var firstTask... 行相关联的错误消息Thread 1: EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0) 崩溃。如果我继续执行,每次前进时都会在线程 1 的顶部获得 EXC_BAD_ACCESS0 misaligned_stack_error_

为什么这个演员阵容会导致这一切?

【问题讨论】:

  • 您能否发布一张显示Task 实体的CoreData 模型屏幕截图,其中Entity Inspector 视图在右侧打开?
  • 很棒的评论。谢谢。它只是让我找到了一个可行的解决方案。
  • 解决方案是什么?

标签: ios core-data swift


【解决方案1】:

确保您的 Class name 字段实际上是 Module.Task,其中 Module 是您的应用程序的名称。 Swift 中的 CoreData 类是命名空间的。现在,您的对象作为 NSManagedObject 而不是作为任务被从上下文中拉出,因此 as-cast 失败了。

【讨论】:

  • 没关系。现在可以工作了。你的建议加上 SiLo 的要求帮助我弄清楚了这一切。我需要在 Core Data 模型实体检查器的 Class 字段中使用 AppName.Task
  • 能否请您在回答中指出您应该在 xcdatamodeld 文件中添加 AppName.Model。我花了一点时间才弄清楚。
  • 如果我在底层数据模型中正确设置了模块名称,我可以让应用程序正常工作并进行转换。我的问题是,在我将 NSManagedObject 转换为我的 Swift 模型的代码行时,我无法在不爆炸的情况下进行测试。任何想法为什么?
  • 我进去了,在类字段的核心数据模型实体检查器中,将app名称放在实体名称之前。它仍然对我不起作用。所以我输入了 .。我仍然收到 EXC_BREAKPOINT 错误。有什么建议吗?
  • 在我看来,这个解决方案不再适用于 XCode 7 beta 2:XCode 7 beta 2 的实体检查器从 AppName.Task -> AppNameTask 中删除了点。 (我在 XCode 6.x 中成功使用了这个解决方案)
【解决方案2】:

如果您尝试了上述所有建议并且没有一个对我有用,这甚至会令人沮丧!

所以这对我有用。

1- 选择您的 xcdatamodeld 文件

2- 确保您的所有实体在“数据模型”中都没有模块 检查员”,如果您看到“型号:当前产品模块”..清除它,使其看起来像附加的图像。

3- 删除您的应用以清除核心数据

4- 如果仍然无法正常工作,请删除您的实体并重新生成它们。

【讨论】:

  • 在我的情况下,我特别缺少的是添加类本身而不是模块。感谢您发布视觉效果,让我明白这一点。
  • 这应该是公认的答案.. 其他答案都不起作用。谢谢@polarwar
【解决方案3】:

您需要修改您的 Task.swift 文件。如下添加@objc(Task)

import CoreData

@objc(Task)
class Task: NSManagedObject {
    @NSManaged var name: String
}

如果您的项目不包含任何 Objective-c 代码,我认为这是一个错误。但是,您需要添加该行直到修复此问题。

我从这里学到的。

Youtube video at 11:45

【讨论】:

    【解决方案4】:

    我猜只更改 .xcdatamodel 中的类字段不再起作用,因为我仍然遇到以下异常: 致命错误:对类使用未实现的初始化程序“init(entity:insertIntoManagedObjectContext:)”

    所以,我在我的自定义类中输入了这段代码:

        init(entity: NSEntityDescription!,
        insertIntoManagedObjectContext context: NSManagedObjectContext!) {
            super.init(entity: entity, insertIntoManagedObjectContext: context)
    }
    

    突然间,它奏效了! NSManagedObject 现在可以向下转换为我的自定义类。 我真的不明白为什么这是解决方案,但它确实有效:)

    【讨论】:

      【解决方案5】:

      XCode 7.1 和 Swift 2.0 下 @Ben Gottlieb 答案的更新

      1. 将@objc 添加到您的班级。见赵欧文的回答。下面是一个例子:
      @objc
      class ImageRecordMO: NSManagedObject{
      
      1. 打开您的 .xcdatamodled 文件。

      2. 选择您的实体并单击右侧面板上的数据模型检查器。

      3. 输入类名,见下图

      4. 选择你的模块为Current Product Module,见下图。

      【讨论】:

      • 是的!太明显了! \o/ 我很遗憾我只能投一票。
      【解决方案6】:

      Xcode 7 + Swift 2

      Person.swift

      @objc(Person)
      class Person: NSManagedObject {
      }
      

      数据模型

      然后简单地调用

      let person = NSEntityDescription.insertNewObjectForEntityForName("Person", inManagedObjectContext: self.managedObjectContext) as! Person
      

      【讨论】:

        【解决方案7】:

        我必须添加@objc() 并在 coredata 接口中设置类。 在 CoreData 右侧窗口的 Entity 区域中,有 Name 和 Class 文本框。 类不能是 MSManagedObject,而是你的类。 我创建了一个simple working example

        【讨论】:

        • 将 nsmanaged 对象转换为自定义的问题,发生在您尝试在测试目标中执行此操作时,而不是在您的示例中的主项目中。
        【解决方案8】:

        过去几天我遇到了这个问题,奇怪的是,对我有用的解决方案是上面建议的变体。

        我将@objc 声明添加到生成的子类中,但删除了对象模型中类名中的任何命名空间前缀(在生成子类后,它的默认前缀为“PRODUCT_MODULE_NAME.”)。那行得通。

        【讨论】:

          猜你喜欢
          • 2012-07-18
          • 1970-01-01
          • 2011-11-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-07
          相关资源
          最近更新 更多