好的,问题在于:我使用managedObjectContext
层次结构。我有一个单managedObjectContext
的根,所以我可以共享相同的上下文,同时我可以有子上下文来分隔保存。
_managedObjectContext = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
_managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
这就是我创建孩子managedObjectContext
的方式,我为每个viewController
创建一个<{1}}
NSManagedObjectContext* childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
childContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
childContext.parentContext = _managedObjectContext;
对于那些认为仅仅保存孩子managedObjectContext
就足够了的人来说,保存只有一个祖先,你必须这样做,直到父亲为nil
。我只有父母和孩子,所以这是我保存数据到存储的代码
- (void)saveChildContext:(NSManagedObjectContext*)childContext
{
[childContext performBlockAndWait:^{
NSError* error;
[childContext save:&error];
[_managedObjectContext performBlock:^{
NSError* parentError;
[_managedObjectContext save:&parentError];
}];
}];
}
我有一个viewController
来获取tableView
的数据。
arrObjects = [dbClient getEntitiesOfType:@"Object" predicate:@"%K == nil || %K.length < 1" predicateArray:[NSArray arrayWithObjects:@"someRelationship.property", @"someRelationship.otherProperty", nil] childContext:childContext];
这就落后了:
- (NSArray*)getEntitiesOfType:(NSString *)entityType predicate:(NSString*)predicateString predicateArray:(NSArray*)predicateArray childContext(NSManagedObjectContext*)context
{
NSManagedObjectContext* managedObjectContext;
if (context != nil)
managedObjectContext = context;
else
managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil)
{
NSEntityDescription* entityDescription = [NSEntityDescription entityForName:entityType inManagedObjectContext:managedObjectContext];
NSPredicate* predicate = [NSPredicate predicateWithFormat:predicateString argumentArray:predicateArray];
NSFetchRequest* request = [[NSFetchRequest alloc] init];
request.entity = entityDescription;
request.predicate = predicate;
NSError* error = [[NSError alloc] init];
return [managedObjectContext executeFetchRequest:request error:&error];
}
else
return nil;
}
在详细了解其中一个获取结果时,我会进行更改,保存上下文,将更改传播到父级,然后再存储。我传递了对象,并且我使用了对象的managedObjectContext
。保存数据到商店后,我弹出我的viewController
,一切都很好。
如果我选择在另一个viewController
上对该对象执行某些操作,我会保存上下文,因为我做了一些更改,传递objectId
,我用另一个managedObjectContext
获取该对象,但是拥有相同的父级,进行更改并将其保存到父级,然后存储。一切都很好地存储。哦,我在这里使用NSNotification
,因为viewControllers
不了解对方的存在。
[self.navigationController popViewControllerAnimated:NO];
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:currentTrip.objectID, @"ObjectId", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"tripRecording" object:nil userInfo:userInfo];
问题是当我到达viewController
(tableViewController
)时,我在viewWillAppear
上获取数据,但我没有得到更改。另一方面,如果我在同一视图上按段,获取另一个数据,然后返回到第一个段,按下它并再次获取第一组数据,我得到正确的答案。这意味着无论我使用哪种上下文,数据都能正确存储。
我的问题是:
除非我更改managedObjectContext
然后再次获取第一个请求,fetchRequest
如何才能看到更改?
reset
上的managedObjectContext
是获取正确数据的唯一途径吗?
感谢。
答案 0 :(得分:1)
以下是我使用两个不同NSManagedObjectContext
:
创建我的主人NSManagedObjectContext
,我从不直接解决这个问题:
- (NSManagedObjectContext *)masterManagedObjectContext {
if (_masterManagedObjectContext != nil) {
return _masterManagedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_masterManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_masterManagedObjectContext performBlockAndWait:^{
[_masterManagedObjectContext setPersistentStoreCoordinator:coordinator];
}];
}
return _masterManagedObjectContext;
}
动态创建新的NSManagedObjectContext
:
- (NSManagedObjectContext *)newManagedObjectContext {
NSManagedObjectContext *newContext = nil;
NSManagedObjectContext *masterContext = [self masterManagedObjectContext];
if (masterContext != nil) {
newContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[newContext performBlockAndWait:^{
[newContext setParentContext:masterContext];
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self
selector:@selector(backgroundDidSaveNotification:)
name:NSManagedObjectContextDidSaveNotification
object:newContext];
}];
}
return newContext;
}
侦听新NSManagedObjectContext
保存的方法,以便它可以合并为master:
- (void)backgroundDidSaveNotification:(NSNotification*)notificaton {
[self.masterManagedObjectContext mergeChangesFromContextDidSaveNotification:notificaton];
[self saveMasterContext];
}
为了清楚起见,我saveMasterContext
:
- (void)saveMasterContext {
[self.masterManagedObjectContext performBlockAndWait:^{
NSError *error = nil;
BOOL saved = [self.masterManagedObjectContext save:&error];
if (!saved) {
// do some real error handling
NSLog(@"Could not save master context due to %@", error);
}
}];
}