【问题标题】:Core Data multi context importing and faulting核心数据多上下文导入和故障
【发布时间】:2013-03-03 10:47:55
【问题描述】:

我有一个主要的NSManagedObjectContext 在几个 UIViewController 中使用来显示数据(这是一个带有Department 列表的UITableView

3 个实体,一个 Department 和一个对一到 Boss 和一个对多到 Employee(在这种情况下,employee 有一个 NSData(这是一个图像)属性和 @987654329 @)。

由于我正在批量导入图像,因此我在后台线程中执行此操作,该线程有自己的NSManagedObjectContext

导入包括创建Boss 实体和所有Employee 并设置关系。

现在我的问题是:

  • 如果我使用child contextmain context 进行导入和保存,那么即使两个上下文都没有变化,所有图像都会保留在内存中。
  • 如果我使用context with no relation to the main context,图像不会保留在内存中,但新数据不会显示在UIViewController 中(显然因为main context 不会通知@987654338 所做的更改@)

所以我希望在内存中没有图像的情况下仍然显示更改(这意味着我希望Department 知道它具有Boss 关系但没有内存中的图像)。简而言之,我希望他们在context 被保存后立即变成故障。

编辑:我认为问题是当我保存child context 时,它与main context 合并,并且新插入的图像从那里保留在内存中:/ 我不知道如何释放它们(没有它们'即使有内存警告也不会自动释放...)

编辑 2:我想我修好了,这就是我所做的:

  • 我使用了一个绑定到main contextchild context,我听了所有的NSManagedObjectContextDidSaveNotification 和所有的inserted updated 我打电话给refreshObject:mergeChanges: 把它变成故障。

我注册了来自每个上下文的所有通知。

-(void)contextDidSave:(NSNotification*)saveNotification {
    NSManagedObjectContext *defaultContext = saveNotification.object;
    NSArray *insertedObjects = [saveNotification.userInfo valueForKey:@"inserted"];
    if (insertedObject) {
        NSLog(@"INSERTED : %@", insertedObjects);
        for (NSManagedObject *object in insertedObjects) {
            [defaultContext refreshObject:object mergeChanges:NO];
        }
    }
    NSArray *updatedObjects = [saveNotification.userInfo valueForKey:@"updated"];
    if (insertedObject) {
        NSLog(@"UPDATED : %@", updatedObjects);
        for (NSManagedObject *object in updatedObjects) {
            [defaultContext refreshObject:object mergeChanges:NO];
        }
    }
}

【问题讨论】:

  • 这听起来像是过早的优化; MOC 应该决定何时为您解决问题。您是否真的遇到了由此引起的问题,或者您只是认为它应该以某种方式工作?
  • 是的,我在 5-7 次批量导入(大约 28Mb 的图像数据/导入)之后,应用程序崩溃了,因为图像永远不会出现故障。
  • 拥有通知似乎有点混乱 - 子上下文应该为您解决这个问题。完成添加和保存后,您不能在子上下文中调用 refreshObject 吗?
  • 我试过了,但我认为对象仍然存在于父上下文中

标签: objective-c core-data


【解决方案1】:

您可以使用refreshObject:mergeChanges: 将特定对象变为故障,为 mergeChanges 参数传递 NO。

Turning object into a fault(标志为 NO)意味着对相关托管对象(即对象具有引用的对象)的强引用被破坏,因此您也可以使用此方法修剪对象的一部分您想要限制内存使用的图表。

Documentation here.

【讨论】:

  • 是的,我知道我在任何地方都读过它,这似乎是唯一的方法,但我尝试调用它,但在这种情况下它似乎不起作用(当我在 main 上调用它时它起作用上下文但不是孩子)我还阅读了我能找到的所有核心数据文档:/
  • 好的,所以我想我找到了一种方法来做我想做的事我会把你的答案标记为有效,但在此之前你能告诉我你对我解决它的方式的看法吗?如果它看起来不错:/?
  • 如果您自己解决了问题,您应该回答自己的问题并接受该答案,而不是编辑问题。
猜你喜欢
  • 2012-10-14
  • 1970-01-01
  • 1970-01-01
  • 2012-09-07
  • 2010-12-22
  • 1970-01-01
  • 2012-03-08
  • 1970-01-01
相关资源
最近更新 更多