Подтвердить что ты не робот

Как сделать назначенный инициализатор для подкласса 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, чтобы использовать мой пример использования?

4b9b3361

Ответ 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
}