2014-10-17 11 views
27
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 
} 

Chcę, aby metodę, która pozwala mi zainicjować nowe obiekty z tej rozmowy:Jak zrobić wyznaczonego inicjatora dla podklasy NSManagedObject w Swift?

let newAlternative = Alternative("third platform", True, entityDescription, managedObjectContext) 

ale pojawia się błąd:

Convenience initializer for Alternative must delegate with self.init 

Co muszę zmienić w moim initalizer aby mój przykład użycia działał?

Odpowiedz

29

wygody inicjator musi wywołać wyznaczonego inicjator na self:

convenience init(text: String, isCorrect: Bool, entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext!) { 
    self.init(entity: entity, insertIntoManagedObjectContext: context) 
    self.text = text 
    self.isCorrect = isCorrect 
} 

która byłaby nazywana jako

let newAlternative = Alternative(text: "third platform", isCorrect: true, 
    entity: entityDescription, insertIntoManagedObjectContext: managedObjectContext) 

Ponadto, można również przejść do tworzenia opisu jednostki do inicjatora wygody zamiast przekazania go jako argument (jak motywowane odpowiedź Mundi jest):

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

Szybkie dodatkowe pytanie @ martin-r: Próbuję umieścić je w rozszerzeniu na NSManagedObject. Czy uważasz, że to powinno być możliwe, ponieważ dostaję błąd kompilacji. Wygląda na to, że należy użyć NS_DESIGNATED_INITIALIZER z NSManagedObject.h. jakieś pomysły? – Damien

+0

@Damien: Nie bez wyświetlenia rzeczywistego kodu i dokładnego komunikatu o błędzie. –

+0

https: //gist.github.com/dglancy/2f1e313cfcc7d61cff8c – Damien

9

ja po prostu to zrobił z funkcją Klasa:

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 
} 

który można nazwać tak (prawie tak ładna):

let item = Item.newInstance(text, notes:notes) 
+0

Czyli nie jest możliwe utworzenie inicjalizatora z 'Alternatywą (" trzecia platforma ", True, entityDescription, managedObjectContext)'? Moja opinia jest taka, że ​​nie wygląda tak dobrze z Alternative.newInstance (...) – hakonbogen

+2

+1 dla * nie * konieczności przekazania opisu encji do inicjalizatora. –

+0

Możesz nadać mu inną nazwę, zamiast "newInstance()". Nadal potrzebujesz parametrów nazwanych, a nie tylko listy parametrów, w przeciwnym razie kod będzie mniej czytelny. - Podsumowując, rozwiązanie metody klasy nie jest tak naprawdę dłuższe ani mniej estetyczne niż inne inicjalizatory. – Mundi

2

Musisz wywołaj inicjalizator z twojego inicjatora wygody. Co więcej, nie zwracasz niczego z jakiegokolwiek inicjalizatora.

Aby spełnić zasady opisane w dokumentacji Swift firmy Apple, potrzebujesz najpierw inicjatora dla swojej podklasy, która wywołuje init() swojej nadklasy, możesz zaoferować inicjator wygody, który może wywoływać tylko wyznaczony inicjator z deklaracji klasy.

To pracować (Aktualizacja. Biorąc pod uwagę fakt, że właściwości podstawowe dane oznaczone @NSManaged są inicjowane automatycznie przez program Dzięki @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) 
} 
+1

Właściwości danych podstawowych (oznaczonych '@ NSManaged') są inicjowane automatycznie przez środowisko wykonawcze. –

+0

Spowoduje to problem. zobacz to pytanie: http://stackoverflow.com/questions/26202346/error-with-swift-and-core-data-fatal-error-use-of-unimplemented-initializer-i – rintaro

2

Swift 3,1 rozwiązania:

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 
} 
Powiązane problemy