web-dev-qa-db-ja.com

SwiftでNSManagedObjectサブクラスの指定イニシャライザを作成する方法は?

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

サンプル使用を機能させるには、イニシャライザーで何を変更する必要がありますか?

30
bogen

便利な初期化子は、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)

さらに、エンティティ記述の作成を、引数として渡すのではなく、便利な初期化子に移動することもできます(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
}
36
Martin R

私は単にクラス関数でこれを行いました:

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, context:context)
10
Mundi

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
}
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)
}
2
marcusficner