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