2015-10-23 10 views
19

Jestem nowym użytkownikiem Swift i próbuję nauczyć się korzystać z Core Data. Ale dostaję tego błędu i nie jestem pewien, co zrobiłem źle. Szukałem w Internecie i wypróbowałem kilka rzeczy, ale nie mogę tego naprawić.Rozwiązywanie "Nie można wywołać określonego inicjalizatora w klasie NSManagedObject"

Failed to call designated initializer on NSManagedObject class 'FirstCoreData.Course' 

Kiedy ta linia wykonuje:

ncvc.currentCourse = newCourse 

W tej funkcji:

class TableViewController: UITableViewController, AddCourseViewControllerDelegate { 

var managedObjectContext = NSManagedObjectContext.init(concurrencyType: NSManagedObjectContextConcurrencyType.MainQueueConcurrencyType) 

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    if segue.identifier == "addCourse" { 
     let ncvc = segue.destinationViewController as! NewCourseViewController 
     ncvc.delegate = self 

     let newCourse = NSEntityDescription.insertNewObjectForEntityForName("Course", inManagedObjectContext: self.managedObjectContext) as! Course 
     ncvc.currentCourse = newCourse 

    } 
} 

klasy generowane przez "Create NSManagedObject podklasy ..." dla podmiotu przedmiotu:

import Foundation 
import CoreData 

class Course: NSManagedObject { 

// Insert code here to add functionality to your managed object subclass 

} 

I:

import Foundation 
import CoreData 

extension Course { 

    @NSManaged var title: String? 
    @NSManaged var author: String? 
    @NSManaged var releaseDate: NSDate? 

} 

Odpowiedz

45

Problem nie leży w kodzie w swoim pytaniu, ale we fragmencie masz włączone jako uwag do drugiej odpowiedzi:

var currentCourse = Course() 

nie tylko deklarują currentCourse być typu Course, i t tworzy także instancję jednostki Course przy użyciu standardowej metody init. Jest to wyraźnie zabronione: Musisz użyć wyznaczonego inicjatora: init(entity entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?). Jest to opisane w dokumentacji Apple here.

Podejrzewam, że nie zawsze używać instancji utworzonego przez powyższej definicji var, więc po prostu zdefiniować go jako rodzaju Course?:

var currentCourse : Course? 

Ponieważ jest opcjonalny, nie trzeba ustawić początkowy wartość, ale musisz odrzucić wartość, gdy jest używana.

+0

Dzięki @pdasdf to działa dobrze dla mnie. – Chetan

+0

Dobra rada! Wspaniały. –

0

Twój currentCourse powinna być klasa NSManagedObject

Proszę odnieść to CoreData: error: Failed to call designated initializer on NSManagedObject class

+0

Jeśli zadeklaruję currentCourse jako NSManagedObject, stracę dostęp do tytułu, autora i członków releaseDate. Tak więc nie wiem, jak uzyskać dostęp do atrybutów encji. – Daniel

+0

Myślę, że currentCourse jest również klasą Course, więc nie stracisz jednostek. – Vijay

+0

Przepraszam, nie rozumiem. W tej chwili mam var currentCourse = Course(). Jeśli zmienię to na var currentCourse = NSManagedObject(), wówczas wszystko, co odnosi się do członków Course (np. CurrentCourse.title), mówi "title nie jest członkiem NSManagedObject". – Daniel

7

Miałem ten sam problem. I instancji obiektu jak to działało, dla kursu byłoby coś takiego:

var currentCourse = Course.init(entity: NSEntityDescription.entityForName("Course", inManagedObjectContext:mox)!, insertIntoManagedObjectContext: mox) 

zamiast:

var currentCourse = Course() 
2

użyłem tego w Xcode 8.3.2 z Swift 3.1.

NSEntityDescription.insertNewObject(forEntityName: String(describing: type(of: Record())), into: managedObjectContext) as! Record 

Otrzymałem ten sam komunikat o błędzie. Ale te dane zostały wstawione do db. Więc może to nie ma znaczenia.

3

Najprostszym sposobem jest to,

  • określić w applicationDelegate odniesienie dla kontekstu
  • instancję zmiennej przepuszczając kontekst

W AppDelegate (poza nawiasach):

let appDelegate = UIApplication.shared.delegate as! AppDelegate 
let context = appDelegate.persistentContainer.viewContext 

I w kodzie:

let currentCourse = Course(context:context) 

Teraz masz utworzoną jednostkę. Ale nie zapomnij zapisać:

appDelegate.saveContext() 
Powiązane problemy