Swift和Core数据出错:致命错误:使用未实现的初始化程序'init(entity:insertIntoManagedObjectContext :)'

cfi*_*her 10 cocoa initialization core-data swift

我有以下继承自的类NSManagedObject:

import Foundation
import CoreData


class Note: NSManagedObject {



    @NSManaged var text: String
    @NSManaged var name: String


     init(name: String, text:String, context: NSManagedObjectContext){

        let entity = NSEntityDescription.entityForName("Note", inManagedObjectContext: context);
        super.init(entity: entity!, insertIntoManagedObjectContext: context)

        self.text = text
        self.name = name;

    }
}
Run Code Online (Sandbox Code Playgroud)

当我创建它的实例时,一切正常,但是当我搜索这些实体时,我得到一个非常奇怪的错误:

fatal error: use of unimplemented initializer 'init(entity:insertIntoManagedObjectContext:)'
Run Code Online (Sandbox Code Playgroud)

这是导致错误的代码:

func coreDatePlayground(){

    var note = Note(name: "A new note", text: "blah", context: self.managedObjectContext!)

    println("\(note.name)  \(note.text)")

    var noote2 = Note(name: "Another note", text: "blah blah", context: self.managedObjectContext!)


    managedObjectContext?.save(nil)

    var fetch = NSFetchRequest(entityName: "Note")
    // This line causes the crash.
    var results = self.managedObjectContext?.executeFetchRequest(fetch, error: nil)
    if let objects = results{
        println(objects.count)
    }

}
Run Code Online (Sandbox Code Playgroud)

我发现改变初始化的方法是让它变得方便,并且调用self而不是super来摆脱这个问题,但我不知道为什么.

 convenience init(name: String, text:String, context: NSManagedObjectContext){

    let entity = NSEntityDescription.entityForName("Note", inManagedObjectContext: context);
    self.init(entity: entity!, insertIntoManagedObjectContext: context)

    self.text = text
    self.name = name;

}
Run Code Online (Sandbox Code Playgroud)

上面的代码有效,但我不知道为什么.谁知道发生了什么事?这是一个错误还是我的错?

rin*_*aro 13

这是记录在案的行为.

默认情况下,Swift子类不继承其超类初始值设定项

例如,以下代码甚至不编译,因为Child不会init(id:String)自动继承.这种机制确保nameChild课堂上正确初始化.

class Parent {
    var id:String
    init(id:String) {
        self.id = id
    }
}

class Child:Parent {
    var name:String
    init(id:String, name:String) {
        self.name = name
        super.init(id: id)
    }
}

var child1 = Child(id:"child1")
Run Code Online (Sandbox Code Playgroud)

如果仅convenience在子类中定义初始值设定项,则它会自动继承其所有超类指定的初始值设定项,如"自动初始化程序继承"部分中所述

  • 但他的第一个代码如何编译呢?它不包括所有指定的初始化器吗? (3认同)

kga*_*dis 9

您必须在NSManagedObject子类中实现以下(这是Swift 3.0版本):

@objc
private override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) {
    super.init(entity: entity, insertInto: context)
}
Run Code Online (Sandbox Code Playgroud)

答案是回答它,但不是直接回答.

这样做的原因是Swift没有默认继承它们的超级调用指定的初始化器,并且在执行读取时使用此初始化器似乎是CoreData(在方法中插入断点).所以在这里我们"提出"指定的CoreData使用的初始化程序.

如果您有NSManagedObject基类,则还必须在其中实现此方法.

致JSQCoreDataKit的想法.

  • 非常感谢,经过 3 小时的调查,你真的节省了我的时间,我刚刚覆盖了基类和子类的初始化程序,它工作得很好 (2认同)