【问题标题】:How can I undo a NSManagedObject deletion without using the built-in undo manager?如何在不使用内置撤消管理器的情况下撤消 NSManagedObject 删除?
【发布时间】:2016-10-14 07:32:48
【问题描述】:

我正在使用 CoreData 和 NSUndoManager 构建一个基于 OSX 文档的应用程序。

我有一个全局 NSUndoManager 来处理撤消和重做,而不是使用每个 NSManagedDocument 中内置的默认值。这意味着我手动注册撤消和重做,而不是依赖它们在托管对象上下文更改时自动注册。

当我从 NSManagedObjectContext 中删除 NSManagedObject 时,我想注册一个撤消来恢复已删除的对象。我知道这是可能的,因为 NSManagedDocument 的内置 NSUndoManager 默认会执行此操作,但在删除对象后尝试使用该对象会引发错误。如何在撤消期间恢复实际对象?

func removeAnObject(object: NSManagedObject) {
    self.managedObjectContext?.deleteObject(object)
    self.project?.undoManager?.registerUndoWithTarget(self, handler: { (object) in

        // how to undelete object???

        self.project?.undoManager?.prepareWithInvocationTarget(self).removeAnObject(object)
    })
}

【问题讨论】:

    标签: swift cocoa core-data nsmanagedobject nsundomanager


    【解决方案1】:

    想通了。简单的答案:

    self.project.undoManager?.insert(object)
    

    棘手的部分是,如果您已将托管对象上下文保存到持久存储中,“对象”的所有属性都将变为空白。但是,如果您事先保存了这些属性的值,则可以在新插入之后重新分配它们。

    func removeAnObject(object: NSManagedObject) {
    
        let property1 = object.property1
        let property2 = object.property2
    
        self.managedObjectContext?.deleteObject(object)
        self.project?.undoManager?.registerUndoWithTarget(self, handler: { (object) in
    
            self.managedObjectContext?.insertObject(object)
            object.property1 = property1
            object.property2 = property2
    
            self.project?.undoManager?.prepareWithInvocationTarget(self).removeAnObject(object)
        })
    }
    

    【讨论】: