Как сделать назначенный инициализатор для подкласса NSManagedObject в Swift?
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
}
Я хочу создать метод, который позволяет мне инициализировать новые объекты с помощью этого вызова:
let newAlternative = Alternative("third platform", True, entityDescription, managedObjectContext)
Но я получаю ошибку:
Convenience initializer for Alternative must delegate with self.init
Что мне нужно изменить в моем initalizer, чтобы использовать мой пример использования?
Ответы
Ответ 1
Инициализатор удобства должен вызывать назначенный инициализатор на self
:
convenience init(text: String, isCorrect: Bool, entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
self.init(entity: entity, insertIntoManagedObjectContext: context)
self.text = text
self.isCorrect = isCorrect
}
который будет называться
let newAlternative = Alternative(text: "third platform", isCorrect: true,
entity: entityDescription, insertIntoManagedObjectContext: managedObjectContext)
Кроме того, вы также можете перенести создание описания сущности в инициализатор удобства вместо передачи его в качестве аргумента (как мотивировано
Мунди):
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
}
Ответ 2
Я просто сделал это с помощью функции класса:
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
}
который вы можете назвать так (почти так же красиво):
let item = Item.newInstance(text, notes:notes)
Ответ 3
Вы должны вызвать назначенный инициализатор из инициализатора удобства.
Кроме того, вы ничего не возвращаете из любого инициализатора.
Чтобы выполнить правила, описанные в документации Apple Swift, вам сначала понадобится назначенный инициализатор для вашего подкласса, который вызывает init() своего суперкласса, тогда вы можете предложить инициализатор удобства, который разрешен только для вызова назначенного инициализатор из его объявления класса.
Это будет работать: ( Обновлено: учтено, что основные свойства данных, помеченные с помощью @NSManaged, автоматически инициализируются средой выполнения. Спасибо @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)
}
Ответ 4
Решение 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
}