在Swift核心数据中向下转换NSManagedObject

时间:2015-11-10 08:54:38

标签: swift core-data nsmanagedobject downcast

我有一个继承自NSManagedObject的类。我正在将此对象用于模型数据,并且它也被持久化。

class Foo: NSManagedObject {

   @NSManaged var firstVar: String
   @NSManaged var secondVar: String

  let entity = NSEntityDescription.entityForName("Foo",   inManagedObjectContext: managedObjectContext)
  let createdManagedObject = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedObjectContext) as? Foo

}

我可以创建对象并获取NSManagedObject实例,但我无法将其转发给实际的类。 实际上,如果我将它转发为可选值,那么我将获得零值,如果我向下展开,那么它将会崩溃。 当使用nil值调试器检查器向下转换显示类型: Module.Foo 时,我认为这是问题的根源。

当然我尝试在.xcmod​​el检查器中命名该类,尝试将实体命名为 Module.Foo ,但从Xcode 7开始不允许后者无论如何。

所有在一起:没有成功。现在我必须通过KV访问Foo对象,这有点尴尬。

有人解决了这个问题吗?

编辑:添加代码以显示创建和向下展示。我遇到了Xcode 7.0的问题,现在与7.1.1相同

4 个答案:

答案 0 :(得分:1)

似乎主要问题是目标。感谢 Martin R 指出我的问题。 问题是,主应用程序中的代码也是部分或另一个目标,类似于测试。当从Core Data检索到对象时,它的类签名是 Target.Foo ,如果您尝试将其强制转换为 Target2 中的Foo,则得到了从Target.Foo转换为Target2.Foo的错误消息,不幸的是,除非日志为空,否则此消息不会显示在日志中?

根本不重要,如果在下面的设置中如何命名类或模块:

enter image description here

唯一重要的是你的.xcmod​​el与访问它的代码位于同一目标中。

答案 1 :(得分:0)

您需要编辑数据模型配置,以告知CoreData将哪个类用于特定实体。实际的实体名称本身对实例化的类没有影响。

enter image description here

答案 2 :(得分:0)

您需要在班级中添加objc注释:

@objc(Foo)
class Foo: NSManagedObject {
   ...
}

答案 3 :(得分:0)

您需要直接实例化Foo-Class:

let createdManagedObject = Foo(entity: entity!, insertIntoManagedObjectContext: managedObjectContext)

如果您仍希望封装代码来管理CoreData,您可以执行类似以下操作:

static func newInstanceForEntityName(name: String, context: NSManagedObjectContext) -> NSManagedObject {

    let anyType: AnyObject.Type = NSClassFromString(name)!
    let nsmType: NSManagedObject.Type = anyType as! NSManagedObject.Type

    let entity = NSEntityDescription.entityForName(name, inManagedObjectContext: context)

    return nsmType.init(entity: entity!, insertIntoManagedObjectContext: context)
}

您可以像以下一样使用它:

let foo = newInstanceForEntityName("Foo", context: context) as! Foo