使用NSPredicate的NSFetchRequest返回正确的结果,但是谁的属性没有更新

时间:2015-10-20 18:21:36

标签: core-data nspredicate nsmanagedobjectcontext nsfetchrequest

我的managedObjectContext层次结构如下:(PSC)&lt ;-( writerMOC - private)&lt ;-( mainMOC - main)&lt ;-( backgroundMOC - private)

我有一个名为"名称"的NSManagedObject。财产是"香蕉"。

在backgroundMOC中,我使用backgroundMOC.objectWithID获取对象的引用,更改NSManagedObject" name"属于" Apple",然后设置它" syncStatus"属性为1(标记为同步),然后使用以下例程递归保存moc:

  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)")
    }
}

一旦保存了最后一个moc,就会调用一个同步例程,它在backgroundMOC上工作,后者向本地存储查询syncStatus为1的所有对象,同样在backgroundMOC上调用此提取。 / p>

    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] ?? []

这正确地返回数组中更新的对象,但是,该对象的syncStatus属性等于0,并且其" name"财产仍然设置为" Banana"。

这真的让我很头疼,我觉得我完全理解了managedObjectContext块应该如何工作,但事实证明这是一个很难解决的问题。

更新 这是提示更新的代码。当轻敲单元格时,从主线程调用此方法。

  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
}

1 个答案:

答案 0 :(得分:0)

保留儿童MOC(主要背景的儿童)充满了问题。我建议为您执行的每个操作创建一个新的子项(aka backgroundMOC)。

如果没有看到所有代码,这看起来就像子上下文不同步一样。

更新

假设您创建的backgroundMOCmainMOC设置为其父级,那么我想知道-objectWithID:及其返回的内容。

我也想知道你的-performBlock:电话。在我的脑海中,线程看起来很好,但更好的测试。尝试更改为-performBlockAndWait:只是为了测试并查看是否存在线程竞争条件。不是永久性的改变,而是将代码部分作为问题的来源消除。