2014-10-05 28 views
8

我有下面的類從NSManagedObject繼承:錯誤與斯威夫特和核心數據:致命錯誤:使用「的init(單位:insertIntoManagedObjectContext :)」未實現初始化的

import Foundation 
import CoreData 


class Note: NSManagedObject { 



    @NSManaged var text: String 
    @NSManaged var name: String 


    init(name: String, text:String, context: NSManagedObjectContext){ 

     let entity = NSEntityDescription.entityForName("Note", inManagedObjectContext: context); 
     super.init(entity: entity!, insertIntoManagedObjectContext: context) 

     self.text = text 
     self.name = name; 

    } 
} 

當我創建它的實例,一切正常,但是當我做這些實體的搜索,我得到一個非常奇怪的錯誤:

fatal error: use of unimplemented initializer 'init(entity:insertIntoManagedObjectContext:)' 

這是導致該錯誤代碼:

func coreDatePlayground(){ 

    var note = Note(name: "A new note", text: "blah", context: self.managedObjectContext!) 

    println("\(note.name) \(note.text)") 

    var noote2 = Note(name: "Another note", text: "blah blah", context: self.managedObjectContext!) 


    managedObjectContext?.save(nil) 

    var fetch = NSFetchRequest(entityName: "Note") 
    // This line causes the crash. 
    var results = self.managedObjectContext?.executeFetchRequest(fetch, error: nil) 
    if let objects = results{ 
     println(objects.count) 
    } 

} 

我發現改變初始化方式,使其成爲一種方便的方式,並調用自我而不是超級解決問題,但我不知道爲什麼。

convenience init(name: String, text:String, context: NSManagedObjectContext){ 

    let entity = NSEntityDescription.entityForName("Note", inManagedObjectContext: context); 
    self.init(entity: entity!, insertIntoManagedObjectContext: context) 

    self.text = text 
    self.name = name; 

} 

上面的代碼工作,但我不知道爲什麼。任何人都知道發生了什麼事?這是一個錯誤還是我的錯?

+0

你知道了嗎?我不覺得答案給出了適當的解釋。 – kgaidis 2016-08-31 01:38:01

回答

11

這是documented的行爲。

Swift subclasses do not inherit their superclass initializers by default

例如,下面的代碼甚至不進行編譯,因爲Child不會自動繼承init(id:String)。這種機制確保在Child類正確初始化。

class Parent { 
    var id:String 
    init(id:String) { 
     self.id = id 
    } 
} 

class Child:Parent { 
    var name:String 
    init(id:String, name:String) { 
     self.name = name 
     super.init(id: id) 
    } 
} 

var child1 = Child(id:"child1") 

如果只定義convenience在子類的初始化,然後將其作爲「自動初始化程序繼承」部分

+3

但是他的第一個代碼是如何編譯的呢?它不包括所有指定的初始值設定項嗎? – Fr4nc3sc0NL 2016-02-12 17:30:33

4

您必須實現您的NSManagedObject子類以下(本中記錄自動繼承其所有的超指定的初始化的是斯威夫特3.0版本):

@objc 
private override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) { 
    super.init(entity: entity, insertInto: context) 
} 

答案是有點回答它,但不是真的直接。

這樣做的原因是,斯威夫特默認情況下不它的用途做回遷時似乎CoreData這個初始化繼承supercalls指定初始化(插入一個斷點的方法來查看)。因此,我們在這裏「調出」CoreData的指定初始化程序以供​​使用。

如果您有NSManagedObject基類,您還必須在這些方法中實現此方法。

Credits to JSQCoreDataKit for the idea

+0

太棒了! .... – GK100 2017-09-07 15:32:13

相關問題