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

后端 未结 4 1793
别那么骄傲
别那么骄傲 2020-12-25 11:10
class Alternative: NSManagedObject {

    @NSManaged var text: String
    @NSManaged var isCorrect: Bool
    @NSManaged var image: NSData
} 

convenience init(text:          


        
相关标签:
4条回答
  • 2020-12-25 11:30

    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
    }
    
    0 讨论(0)
  • 2020-12-25 11:34

    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)
    }
    
    0 讨论(0)
  • 2020-12-25 11:54

    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)
    
    0 讨论(0)
  • 2020-12-25 11:56

    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
    }
    
    0 讨论(0)
提交回复
热议问题