Ios 在UI中将NSManagedObject用作数据对象

Ios 在UI中将NSManagedObject用作数据对象,ios,core-data,magicalrecord,Ios,Core Data,Magicalrecord,我做了一个简单的演示应用来说明一个问题 假设我有一个具有以下上下文结构的Master-Detail应用程序: managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) let detailVCContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType) detailVCCont

我做了一个简单的演示应用来说明一个问题

假设我有一个具有以下上下文结构的Master-Detail应用程序:

managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)

let detailVCContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
detailVCContext.parentContext = managedObjectContext

let deleteContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
deleteContext.parentContext = managedObjectContext
我使用
detailVCContext
作为草稿行,在detailvc中编辑/撤消/保存数据

我使用
deleteContext
作为删除数据的上下文(模拟推送通知,可能需要删除一些数据)

假设我将
NSManagedObject
detailVCContext
传递给detailviewcontroller,在这里我显示模型中的数据并对其进行修改。打开DetailVC后,我立即从
deleteContext
中的存储中删除此模型:

            let deletableID = object.objectID
            deleteContext.performBlock({ () -> Void in
                let itemInContext = deleteContext.objectWithID(deletableID)
                deleteContext.deleteObject(itemInContext)
                var error: NSError?
                deleteContext.save(&error)
                if (error != nil) {
                    abort()
                }

                deleteContext.parentContext?.save(&error)
                if (error != nil) {
                    abort()
                }
            })
这将导致详细访问模型的任何属性(或保存它)并导致

***由于未捕获的异常“NSObjectInaccessibleException”,正在终止应用程序,原因:“CoreData无法完成 “0xd0000000000c0000”的故障 ''


这是否意味着我不能将NSManagedObject用作数据模型?我需要把它换成别的类吗

*更新*

看起来我被我的代码弄糊涂了

DetailVC
中所有与UI相关的代码都在
managedObjectContext
上工作(我传递模型对象,在managedObjectContext中获取)

当我将对象传递给
DetailVC
时,我会:

if let detail: AnyObject = self.detailItem {
    if let label = self.detailDescriptionLabel {
        label.text = detail.valueForKey("timeStamp")!.description
    }
}
当我按下保存按钮时,我会:

@IBAction func saveButtonClicked(sender: AnyObject) {
    detailItem?.setValue(NSDate(), forKey: "timeStamp")
    let saveId = detailItem!.objectID
    detailVCContext.performBlock { () -> Void in
        let itemInContext = self.detailVCContext.objectWithID(saveId)

        var error: NSError?
        self.detailVCContext.save(&error)

        if let error = error  {
            abort()
        }
    }
}

就像幽灵杀手教你的,不要越界

基本规则是,任何试图跨线程边界携带
NSManagedObject
的行为都是不安全的。您最多可以发送
managedObjectID

就在这里,你把物体传过去

deleteContext.performBlock({ () -> Void in
                let itemInContext = deleteContext.objectWithID(object.objectID)
所以你能做的就是

let deletableID = object.objectID

deleteContext.performBlock({ () -> Void in
                    let itemInContext = deleteContext.objectWithID(deletableID)
不相关但也可能给你带来问题的是

let detailVCContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
detailVCContext.parentContext = managedObjectContext

此上下文不适合UI操作,因为所有UI工作都必须在主队列上进行。

您想要一个一次性上下文作为草稿行。用户编辑,如果他保存您保存上下文,如果他取消,您只需扔掉它。我将遵循以下模式:

  • 在显示详细信息控制器之前,请使用
    MainQueueConcurrencyType
    创建新的即席子上下文
  • 通过
    NSManagedObjectID
    获取要编辑的对象,并将其传递给细节控制器(例如在
    prepareForSegue
    中)。还可以传递新的上下文
  • 如果发生保存,则通知父控制器。它还应该保存上下文并更新UI
我已经根据您的建议更新了代码,但它仍然存在同样的问题:对象从何而来。它的地址看起来无效。是的,原因地址无效,因为在打开DetailVC之后,我立即从存储器中删除了该对象。您似乎在描述删除对象后想要使用该对象?是的,我想安全地与删除的对象交互(读取其属性),但似乎无法使用CoreData?