我有一个NSManagedObjectContext
与主要帖子(mainContext
)相关联,在那里我获取了整个应用中显示的所有NSManagedObject
。
用户不要编辑这些对象,但我会从Web服务获得更新。我会定期对这些服务执行异步调用,并且他们会告诉"我必须删除哪些托管对象(如果有的话),必须使用新信息(如果有的话)更新哪些托管对象,以及是否需要插入新对象。
因此,我需要首先获取所有服务的响应,然后检查我必须对我mainContext
中已有的托管对象进行哪些更改。我还需要执行更新,以避免阻止UI。
我正在考虑两种方法来管理这种情况:
privateContext
,以插入从服务获得的所有对象。然后以某种方式(如何?)与mainContext
中的对象进行比较,并删除/修改/插入mainContext
中的对象。privateContext
,但要成为mainContext
的子级。然后我需要传递子对象我在其父mainContext
中的对象(这可能吗?怎么样?),同时在这个子上下文中插入我从服务获得的对象,然后比较并执行更改。哪种方法最好或最合适?或者也许它应该是我想不到的另一个?
提前致谢
编辑:这可能是另一种可能的方式吗?:
mainContext
,因为我正在解析服务的响应,而不是创建新对象,只需逐个对mainContext
进行更改...... 编辑2:另一种可能性?:
privateContext
,获取服务响应并创建新对象。然后,还使用此privateContext
获取已存在的所有对象(这与mainContext
中的对象相同)。在此privateContext
中进行更改,比较两组对象(最近从服务和已提取的对象创建),保存此上下文,清除mainContext
并重新获取mainContext
中的所有对象。 / LI>
醇>
答案 0 :(得分:0)
我不确定这是一个完整的答案,但我正在处理类似的情况。我采用的实现路径是使用子对象(遍布整个地方) - 或者更像是临时子上下文所需的。
但是,我要提到的第一件事是确保使用 CoreData 调试功能构建到XCOde中。我制作了第二个具有
的Run-Scheme-com.apple.CoreData.ConcurrencyDebug 1
在应用程序初始化我有我的正常NSManagedObjectContext
- 它被传递给我的后台网络线程。
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[child setParentContext:parentObjectContext];
然后每当我需要从父母传给孩子时,我最终会这样做:
[child objectWithID:(object-in-parent-context)]
或者我最终在做
__block AHRS_RPYL * ret;
[[self getChildContext] performBlockAndWait:^{
ret = [NSEntityDescription insertNewObjectForEntityForName:@"RPYL" inManagedObjectContext:[self getChildContext]];
// ... lots of code
}];
我不能说我真的“喜欢”这种方法,而且我现在仍然坚持使用它,但它看起来确实运作得很好。
在我的大多数视图控制器之间,我有一个
@synthesize managedObjectContext;
在我的prepareForSegue
方法
// Pass on managedObjectContext
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// dispatch_async(dispatch_get_main_queue(), ^{
// If the destination VC is able to take teh setManagedObjectContext method the current objectContext will be passed along.
if ([segue.destinationViewController respondsToSelector:@selector(setManagedObjectContext:)]) {
[segue.destinationViewController performSelector:@selector(setManagedObjectContext:)
withObject:self.managedObjectContext];
} else {
NSLog(@"Segue to controller [%@] that does not support passing managedObjectContext", [segue destinationViewController]);
}
// });
}
CoreData
,因为无论你如何看待它CoreData
都不是最友好的线程选择。实际上,我每50条消息保存到子上下文,并且每250条保存到父级(看起来很久没有触及此代码)。我不能保证这是最好的正确方法,但它确实有效,并且确实将光盘访问保持在最低限度。我得到了很多像20+一样的消息,所以我想做这种堆栈类型。你可能不在乎
(self.getChild())返回子上下文 - 我留下的旧代码。
if (msgCount % 50 == 0) {
// Child Save!
// NSLog(@"Saving SDatas");
__block NSManagedObjectContext *currentChild = [self getChildContext];
[self incChildContext];
// Parent-Child save methodology
[currentChild performBlock:^{
NSError *error;
if (![currentChild save:&error]) {
NSLog(@"\n error => %@ \n", [error localizedDescription]);
NSLog(@" error => %@ ", [error userInfo]);
[NSException raise:@"Database Write Error" format:@"%@ %@", [error localizedDescription], [error userInfo]];
// abort();
}
if (msgCount % 250 < 5) {
[parentObjectContext performBlock:^{
NSError *error;
if (![parentObjectContext save:&error]) {
NSLog(@"\n error => %@ \n", [error localizedDescription]);
NSLog(@" error => %@ ", [error userInfo]);
[NSException raise:@"Database Write Error" format:@"%@ %@", [error localizedDescription], [error userInfo]];
// abort();
}
}];
}
[currentChild reset];
}];
}
[childContext performBlock:^{
// LOTS OF CODE
// to build a query set of the records we want to kill
// End lots of code
[childContext deleteObject:msg];
if (i % modFactor == 0) {
self.percentDone = i / totalRecords;
NSLog(@"%.1f Saving ...", self.percentDone * 100);
NSError *error;
if (![childContext save:&error]) {
NSLog(@"\n error => %@ \n", [error localizedDescription]);
NSLog(@" error => %@ ", [error userInfo]);
[NSException raise:@"Database Write Error" format:@"%@ %@", [error localizedDescription], [error userInfo]];
// abort();
}
[parentContext performBlock:^{
NSError *errrror;
if (![parentContext save:&errrror]) {
NSLog(@"\n error => %@ \n", [error localizedDescription]);
NSLog(@" error => %@ ", [error userInfo]);
[NSException raise:@"Database Write Error" format:@"%@ %@", [error localizedDescription], [error userInfo]];
// abort();
}
}];
}
}];
再次 - 就像我之前所说,这可能不是最好的做事方式,但我确实有一个父/子堆栈,它确实有效。这是我编写的第一批iOS应用程序之一,并且我再次尝试使用核心数据并使用其他内容。
我们有一个非常高的更新率,所以当我们使用单个堆栈时,它使UI非常慢。迁移到父/子的速度很慢 - 如果我再次这样做,我认为它会更顺畅,因为我会编写许多辅助函数来处理其中一些(或者只是使用swift)。
祝你好运。