How to make a designated initializer for NSManagedObject subclass in Swift?

旧城冷巷雨未停 提交于 2019-11-30 02:54:05

A convenience initializer must call the designated initializer on self:

convenience init(text: String, isCorrect: Bool, entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
    self.init(entity: entity, insertIntoManagedObjectContext: context)
    self.text = text
    self.isCorrect = isCorrect
}

which would be called as

let newAlternative = Alternative(text: "third platform", isCorrect: true,
     entity: entityDescription, insertIntoManagedObjectContext: managedObjectContext)

In addition, you could also move the creation of the entity description into the convenience initializer instead of passing it as an argument (as motivated by Mundi's answer):

convenience init(text: String, isCorrect: Bool, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
    let entity = NSEntityDescription.entityForName("Alternative", inManagedObjectContext: context)!
    self.init(entity: entity, insertIntoManagedObjectContext: context)
    self.text = text
    self.isCorrect = isCorrect
}

I simply did this with a class function:

class func newInstance(text: String, notes:String, 
                    context: NSManagedObjectContext) -> Item {
    var item = NSEntityDescription.insertNewObjectForEntityForName("Item", 
               inManagedObjectContext: context) as Item
    item.notes = notes
    item.text = text
    return item
}

which you can call like this (almost as pretty):

let item = Item.newInstance(text, notes:notes, context:context)

Swift 3.1 solution:

convenience init(text: String, isCorrect: Bool, image: NSData, moc: NSManagedObjectContext) {
        let entity = NSEntityDescription.entity(forEntityName: "Alternative", in: moc)
        self.init(entity: entity!, insertInto: moc)
        // vars
        self.text = text
        self.isCorrect = isCorrect
        self.image = image
}

You have to call a designated initializer from your convenience initializer. Also, you do not return anything from any initializer.

To fulfill the rules, which are described in Apple's Swift documentation you first need a designated initializer for your subclass, which calls the init() of its superclass, then you can offer a convenience initializer which is only allowed to call a designated initializer from its class declaration.

This would work: (Updated: Taken into account that core data properties marked with @NSManaged are initialized automatically by the runtime. Thanks @Martin R)

init(text: String, isCorrect: Bool, image: NSData, entity: NSEntityDescription,   insertIntoManagedObjectContext context: NSManagedObjectContext!) {
    super.init(entity: entity, insertIntoManagedObjectContext: context)
}

convenience init(text: String, isCorrect: Bool, entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
    self.init(text: text, isCorrect: isCorrect, entity: entity, insertIntoManagedObjectContext: context)
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!