【发布时间】:2014-07-10 12:52:18
【问题描述】:
好的,问题来了:我使用managedObjectContext 层次结构。我有一个根 managedObjectContext 是单例的,所以我可以共享相同的上下文,同时我可以有子上下文来分离保存。
_managedObjectContext = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
_managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
这就是我创建子managedObjectContext 的方式,每个viewController 都有一个
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 上获取数据,但我没有得到任何更改。另一方面,如果我在同一视图上按下段,获取另一个数据,然后返回第一个段,按下它并再次获取第一组数据,我会得到正确的答案。这意味着无论我使用哪种上下文,数据都得到了正确存储。
我的问题是:
除非我更改
fetchRequest然后再次获取第一个请求,否则managedObjectContext怎么可能看不到更改?reset上的managedObjectContext是获取正确数据的唯一方法吗?
谢谢。
【问题讨论】:
-
1.向我们展示您的代码。 2. 请记住格式化您的问题,使它们看起来更好、更易读。
-
@Neeku 感谢您的评论
-
您应该使用
NSPrivateQueueConcurrencyType而不是NSMainQueueConcurrencyType创建您的子上下文。这是我看到的第一件事。这是一个相当密集的问题,所以我想在提供完整答案之前多看看。 -
@random 但我想成为主线程...
-
@StanleyKubrick 只是因为它是
NSPrivateQueueConcurrencyType并不意味着它不在主线程上。你应该只有一个NSMainQueueConcurrencyType,这是你的master上下文。您创建NSPrivateQueueConcurrencyType的子上下文,该上下文引用回您的单个NSMainQueueConcurrencyType
标签: ios objective-c core-data nsmanagedobjectcontext