2014-10-17 61 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 
} 

我想打,让我初始化新对象与此调用的方法:如何在Swift中为NSManagedObject子类创建指定的初始值设定项?

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

,但我得到的错误:

Convenience initializer for Alternative must delegate with self.init 

我需要什么,我initalizer改变使我的示例使用工作?

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) 

回答

29

的简便初始化必须调用指定的初始化上self

+0

快速的额外问题@ martin-r:我试图将这些放入NSManagedObject的扩展中。你认为这应该是可能的,因为我得到一个编译错误。它似乎在寻找NSManagedObject.h中使用的NS_DESIGNATED_INITIALIZER。有什么想法吗? – Damien 2014-10-18 18:30:18

+0

@Damien:不是没有看到实际的代码和确切的错误信息。 – 2014-10-18 19:04:12

+0

https://gist.github。com/dglancy/2f1e313cfcc7d61cff8c – Damien 2014-10-18 19:12:02

9

我简单地用一个类的函数这样做:

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 
} 
+0

所以它不可能通过'Alternative(“third platform”,True,entityDescription,managedObjectContext)''指定一个初始化程序。我的观点是,它看起来不像Alternative.newInstance(...) – hakonbogen 2014-10-17 15:48:24

+2

+1,因为*不需要将实体描述传递给初始化程序。 – 2014-10-17 15:53:20

+0

你可以给它另一个名字来代替'newInstance()'。此外,您仍然需要命名参数,而不仅仅是参数列表,否则您的代码的可读性会降低。总之,类方法的解决方案并不比其他初始化方法更长或更不美观。 – Mundi 2014-10-18 08:13:53

2

你必须从您的便捷初始值设定项调用指定的初始化程序。 此外,您不会从任何初始化程序返回任何内容。

为了实现苹果Swift文档中描述的规则,您首先需要为您的子类指定初始化程序,该初始化程序调用其超类的init(),然后您可以提供一个仅允许调用从它的类声明中指定初始化器。

这将工作:(更新:考虑到标有@NSManaged核心数据的属性,由运行时自动初始化由于@马丁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

核心数据属性(用@ NSManaged标记)由运行时自动初始化。 – 2014-10-17 15:57:33

+0

这会导致问题。看到这个问题:http://stackoverflow.com/questions/26202346/error-with-swift-and-core-data-fatal-error-use-of-unimplemented-initializer-i – rintaro 2014-10-17 17:08:55

2

夫特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 
} 
相关问题