Core data NSFetchRequest与NSPredicate返回正确的结果,但谁';s属性为';t更新
我的managedObjectContext层次结构如下:(PSC)保持子MOC(主上下文的子上下文)充满了问题。我建议为您执行的每个操作创建一个新的子对象(也称为backgroundMOC) 在没有看到所有代码的情况下,这看起来像是子上下文不同步的问题 更新 假设您创建的Core data NSFetchRequest与NSPredicate返回正确的结果,但谁';s属性为';t更新,core-data,nspredicate,nsmanagedobjectcontext,nsfetchrequest,Core Data,Nspredicate,Nsmanagedobjectcontext,Nsfetchrequest,我的managedObjectContext层次结构如下:(PSC)保持子MOC(主上下文的子上下文)充满了问题。我建议为您执行的每个操作创建一个新的子对象(也称为backgroundMOC) 在没有看到所有代码的情况下,这看起来像是子上下文不同步的问题 更新 假设您创建的backgroundMOC将mainMOC设置为其父对象,那么我想知道-objectWithID:及其返回的内容 我还想知道您的-performBlock:呼叫。在我看来,线程看起来不错,但更好的测试。尝试更改为-perfor
backgroundMOC
将mainMOC
设置为其父对象,那么我想知道-objectWithID:
及其返回的内容
我还想知道您的-performBlock:
呼叫。在我看来,线程看起来不错,但更好的测试。尝试更改为-performBlockAndWait:
,以测试并查看是否存在线程争用情况。这不是一个永久性的更改,但消除了作为问题来源的代码部分。保留子MOC(主上下文的子级)充满了问题。我建议为您执行的每个操作创建一个新的子对象(也称为backgroundMOC)
在没有看到所有代码的情况下,这看起来像是子上下文不同步的问题
更新
假设您创建的backgroundMOC
将mainMOC
设置为其父对象,那么我想知道-objectWithID:
及其返回的内容
我还想知道您的
-performBlock:
呼叫。在我看来,线程看起来不错,但更好的测试。尝试更改为-performBlockAndWait:
,以测试并查看是否存在线程争用情况。这不是一个永久性的更改,但消除了作为问题来源的代码部分。我应该注意,saveManagedContext方法始终在作为第一个参数传递的上下文的performBlock中调用。我应该注意,saveManagedContext方法始终在作为第一个参数传递的上下文的performBlock中调用。我将试试看。感谢如果不起作用,请共享更新对象状态和同步的代码。还有一些其他的边缘可能性。它不起作用,同样的问题。我添加了更改对象属性的代码。我已经附上了大部分的同步代码,还有什么你想看的吗?(CoreDataController.sharedInstance.saveManagedContext引用了以前附加的保存例程。)顺便说一句,我以前对backgroundMOC的所有引用现在都调用了CoreData控制器的NewBackgroundManagedObject函数,这给了我一个主上下文的新的子moc,它没有保留。因此,抓取现在发生在其中一个上。这一更改似乎没有破坏我的代码库中的任何内容。同样值得注意的是,如果我将updateNameForCell()中的逻辑移到主上下文中,所有操作都会很好地进行。我会尝试一下。感谢如果不起作用,请共享更新对象状态和同步的代码。还有一些其他的边缘可能性。它不起作用,同样的问题。我添加了更改对象属性的代码。我已经附上了大部分的同步代码,还有什么你想看的吗?(CoreDataController.sharedInstance.saveManagedContext引用了以前附加的保存例程。)顺便说一句,我以前对backgroundMOC的所有引用现在都调用了CoreData控制器的NewBackgroundManagedObject函数,这给了我一个主上下文的新的子moc,它没有保留。因此,抓取现在发生在其中一个上。这一变化似乎并没有破坏我的代码库中的任何东西。同样值得注意的是,如果我将updateNameForCell()中的逻辑移到主上下文中,所有这些都可以很好地工作。
func saveManagedContext(moc: NSManagedObjectContext, shouldSync: Bool = true, completion: (() -> Void)? = nil)
{
print("\nSaving managed object context...")
do {
try moc.save()
if let parentContext = moc.parentContext {
parentContext.performBlock {
self.saveManagedContext(parentContext, shouldSync: shouldSync, completion: completion)
}
}
else {
if shouldSync { SyncEngine.sharedInstance.synchronize(shouldPushUpdates: true) }
completion?()
}
print("Finished saving managed object context...")
} catch {
logger.error("\(error)")
}
}
let fetchRequest = NSFetchRequest(entityName: entity.name)
let syncPredicate = NSPredicate(format: "%K == %d", JSONKey.SyncStatus.rawValue, 1)
fetchRequest.predicate = syncPredicate
return try backgroundMOC.executeFetchRequest(fetchRequest) as? [SyncableManagedObject] ?? []
func updateNameForCell(cell: UITableViewCell)
{
///gets the object id from the fetchedResultsController
guard let fruitMetaID = tableController.objectIDForCell(cell) else { return }
let backgroundMOC = CoreDataController.sharedInstance.newBackgroundManagedObjectContext()
backgroundMOC.performBlock {
do {
guard let fruit = (backgroundMOC.objectWithID(fruitMetaID) as? FruitMetaData)?.fruit else {
throw //Error
}
print(fruit.name) // "Banana"
fruit.name = "Apple"
fruit.needsSynchronization() //Sets syncStatus to 1
CoreDataController.sharedInstance.saveManagedContext(backgroundMOC)
}
catch {
//handle error
}
}
}
/// The parent to all other NSManagedObjectContexts. Responsible for writting to the store.
lazy var writerManagedObjectContext: NSManagedObjectContext =
{
let managedObjectContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
managedObjectContext.performBlockAndWait {
managedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator
}
return managedObjectContext
}()
lazy var mainManagedObjectContext: NSManagedObjectContext =
{
let managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.performBlockAndWait {
managedObjectContext.parentContext = self.writerManagedObjectContext
}
return managedObjectContext
}()
/// The context associated with background syncing..
func newBackgroundManagedObjectContext() -> NSManagedObjectContext
{
let backgroundManagedObjectContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
backgroundManagedObjectContext.performBlockAndWait {
backgroundManagedObjectContext.parentContext = self.mainManagedObjectContext
}
return backgroundManagedObjectContext
}