覆盖 initWithEntity:insertIntoManagedObjectContext:

Override initWithEntity:insertIntoManagedObjectContext:

我对 initWithEntity:insertIntoManagedObjectContext: 有点困惑。 根据 Swift documentation(Two-Phase Initialization),我应该在初始化子类的所有新属性后调用 super.init。 但是当我用下面的代码这样做时,我得到了错误:

//In subclass of NSManagedObject
init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?, origin: NavCoordinate, destination:NavCoordinate, city: String, averageSpeedKmPH:NSNumber, client:String)
    {
        self.origin = origin
        self.destination = destination
        self.city = city
        self.averageSpeedKmPH = averageSpeedKmPH
        self.client = client
        super.init(entity: entity, insertIntoManagedObjectContext: context)
    }

问题是我收到错误:"Super.init called multiple times in initializer"

如果我先调用 super.init... 就可以了。

initWithEntity:insertIntoManagedObjectContext 的文档也说:

If you override initWithEntity:insertIntoManagedObjectContext:, you must ensure that you set self to the return value from invocation of super’s implementation, as shown in the following example:

但没有任何例子。 覆盖 initWithEntity:insertIntoManagedObjectContext: 的正确方法是什么?

init(entity entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?) 的文档说

You are discouraged from overriding this method—you should instead override awakeFromInsert and/or awakeFromFetch (if there is logic common to these methods, it should be factored into a third method which is invoked from both). If you do perform custom initialization in this method, you may cause problems with undo and redo operations.

正确的方法是覆盖 awakeFromInsert 而不是 init。

我决定先调用 insertNewObjectForEntityForName,然后在实体上调用 setup 来解决。这似乎是最好的解决方案,因为这样你就不会破坏 Swift Two-Phase Initialization 并支持核心数据撤消、重做。

let journey = NSEntityDescription.insertNewObjectForEntityForName("JourneyEntity", inManagedObjectContext: moc) as! Journey
journey.setupJourney(origin, destination: destination, city: city, averageSpeedKmPH: self.user.averageSpeedKmPH, client:client)