gpt4 book ai didi

ios - 受管对象上下文未合并来自后台上下文的更改

转载 作者:行者123 更新时间:2023-12-01 16:50:26 26 4
gpt4 key购买 nike

我有一个双重托管对象上下文设置,其中有一个父/子MOC关系。父级负责直接写入专用队列(NSPrivateQueueConcurrencyType)上的数据库,然后我有一个子级上下文,负责为主线程(NSMainQueueConcurrencyType)提取和保存数据。

当我对主队列上下文进行更改并将其保存后,上下文将按应有的方式工作,然后将更改合并到后台队列上下文中,并在后台线程上将其写入数据库。

我遇到的问题是当我直接将数据写入后台队列上下文,然后尝试将其合并到主队列上下文中时。这些对象已正确存储在商店中,并且当我合并更改时,它似乎可以正常工作。但是,如果我尝试在将数据保存到存储后直接针对主队列上下文发出NSFetchRequest,则数据是过时的,而不是正确的更新数据。

下面的代码摘录应该有助于您了解我在做什么。需要注意的一些事情是从JSON返回NSManagedObjects的逻辑。此外,我已经测试过,并且mergeChangesFromContextDidSaveNotification在UI尝试针对主队列MOC发出任何获取请求之前运行。你们都有什么想法吗?

// Context Setup
- (NSManagedObjectContext *)backgroundWriterManagedObjectContext
{
if (_backgroundWriterManagedObjectContext != nil)
return _backgroundWriterManagedObjectContext;

NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
{
_backgroundWriterManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
_backgroundWriterManagedObjectContext.persistentStoreCoordinator = coordinator;
_backgroundWriterManagedObjectContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy;
_backgroundWriterManagedObjectContext.undoManager = nil;
}
return _backgroundWriterManagedObjectContext;
}

- (NSManagedObjectContext *)managedObjectContext
{
if (_managedObjectContext != nil)
return _managedObjectContext;

NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
{
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_managedObjectContext.parentContext = _backgroundWriterManagedObjectContext;
_managedObjectContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy;
_managedObjectContext.stalenessInterval = 0.0;
}
return _managedObjectContext;
}

// save MOC
- (void)saveManagedObjectContext
{
@try
{
// perform synchronous process to save to the main MOC
[_managedObjectContext performBlockAndWait:^(void)
{
__block NSError *error = nil;

// push any changes in the main context to the background writer context
if (![_managedObjectContext tryLock])
[VS_Log VS_LogError:[NSString stringWithFormat:@"VS_CoreDataManger - Unable To Lock Managed Object Context: %@", error.localizedDescription]];

if (![_managedObjectContext save:&error])
[VS_Log VS_LogError:[NSString stringWithFormat:@"VS_CoreDataManger - Error Saving Managed Object Context: %@", error.localizedDescription]];

[_managedObjectContext unlock];

// save the background writer context
[_backgroundWriterManagedObjectContext performBlock:^(void)
{
error = nil;

if (![_backgroundWriterManagedObjectContext tryLock])
[VS_Log VS_LogError:[NSString stringWithFormat:@"VS_CoreDataManger - Unable To Lock Background Writer Managed Object Context: %@", error.localizedDescription]];

if (![_backgroundWriterManagedObjectContext save:&error])
[VS_Log VS_LogError:[NSString stringWithFormat:@"VS_CoreDataManger - Error Saving Background Writer Managed Object Context: %@", error.localizedDescription]];

[_backgroundWriterManagedObjectContext unlock];
}];
}];
}
@catch (NSException *exception)
{
[VS_Log VS_LogException:exception];
}
}

// This code runs when attempting to save objects from a web service call
[_backgroundWriterManagedObjectContext performBlock:^(void)
{
// create a new process object and add it to the dictionary
__block VS_CoreDataRequest *request = [[VS_CoreDataRequest alloc] init];

// .. LOGIC HERE DESERIALIZES THE JSON AND RETURNS AN ARRAY OF NSMANAGEDOBJECTS

// perform synchronous process to save to the main MOC
@try
{
NSError *error = nil;

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mergeChangesFromContextDidSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:_backgroundWriterManagedObjectContext];

if (![_backgroundWriterManagedObjectContext tryLock])
[VS_Log VS_LogError:[NSString stringWithFormat:@"VS_CoreDataManger - Unable To Lock Background Writer Managed Object Context: %@", error.localizedDescription]];

if (![_backgroundWriterManagedObjectContext save:&error])
[VS_Log VS_LogError:[NSString stringWithFormat:@"VS_CoreDataManger - Error Saving Background Writer Managed Object Context: %@", error.localizedDescription]];

[_backgroundWriterManagedObjectContext unlock];

// submit changes back to the forground context
[_managedObjectContext performBlock:^(void)
{
NSMutableArray *objects = [[NSMutableArray alloc] init];

// iterate through the updated objects and find them in the main thread MOC
for (VS_BaseManagedObject *object in request.objects)
{
// get the object from the main managed object context
NSError *error;
NSManagedObject *obj = [_managedObjectContext existingObjectWithID:object.objectID error:&error];

if (error)
[VS_Log VS_LogError:[NSString stringWithFormat:@"VS_CoreDataManager - Error: %@", error.localizedDescription]];

if (obj)
{
[_managedObjectContext refreshObject:obj mergeChanges:YES];
[objects addObject:obj];
}
}

// RETURN FROM METHOD SO UI CAN REGAIN CONTROL
}];
}
@catch (NSException *exception)
{
[VS_Log VS_LogException:exception];
return;
}
}];

// Merges changes from parent to child context
- (void)mergeChangesFromContextDidSaveNotification:(NSNotification *)notification
{
// remove observer
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:_backgroundWriterManagedObjectContext];

// merge the changes
[_managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
}

最佳答案

您不是在调用流程挂起的更改。

关于ios - 受管对象上下文未合并来自后台上下文的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16482788/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com