ios - existing - query core data swift 4
¿Cómo hacer un inicializador designado para la subclase NSManagedObject en Swift? (4)
class Alternative: NSManagedObject {
@NSManaged var text: String
@NSManaged var isCorrect: Bool
@NSManaged var image: NSData
}
convenience init(text: String, isCorrect: Bool, entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
let alternative = Alternative(entity: entity, insertIntoManagedObjectContext: context) as Alternative
alternative.text = text
alternative.isCorrect = isCorrect
return alternative
}
Quiero hacer un método que me permita inicializar nuevos objetos con esta llamada:
let newAlternative = Alternative("third platform", True, entityDescription, managedObjectContext)
Pero me sale el error:
Convenience initializer for Alternative must delegate with self.init
¿Qué debo cambiar en mi iniciador para que funcione mi ejemplo de uso?
Debe llamar a un inicializador designado desde su inicializador de conveniencia. Además, no devuelve nada de ningún inicializador.
Para cumplir las reglas, que se describen en la documentación de Swift de Apple, primero necesita un inicializador designado para su subclase, que llama a init () de su superclase, luego puede ofrecer un inicializador de conveniencia que solo puede llamar a un inicializador designado desde su declaración de clase
Esto funcionaría: ( Actualizado: se tomó en cuenta que las propiedades de datos centrales marcadas con @NS administradas se inicializan automáticamente por el tiempo de ejecución. Gracias @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)
}
Simplemente hice esto con una función de clase:
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
}
que puedes llamar así (casi igual de bonito):
let item = Item.newInstance(text, notes:notes, context:context)
Solución Swift 3.1 :
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
}
Un inicializador de conveniencia debe llamar al inicializador designado en self
:
convenience init(text: String, isCorrect: Bool, entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
self.init(entity: entity, insertIntoManagedObjectContext: context)
self.text = text
self.isCorrect = isCorrect
}
que se llamaría como
let newAlternative = Alternative(text: "third platform", isCorrect: true,
entity: entityDescription, insertIntoManagedObjectContext: managedObjectContext)
Además, también podría mover la creación de la descripción de la entidad al inicializador de conveniencia en lugar de pasarla como argumento (motivado por la respuesta de Mundi):
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
}