Ios 有问题的NSManagedObject随时间累积
我有一个应用程序,它不断地从TCP/IP端点接收XML消息流。收到每条消息后,应用程序将其内容分解为一组核心数据实体。这是通过三个上下文结构实现的:Ios 有问题的NSManagedObject随时间累积,ios,core-data,Ios,Core Data,我有一个应用程序,它不断地从TCP/IP端点接收XML消息流。收到每条消息后,应用程序将其内容分解为一组核心数据实体。这是通过三个上下文结构实现的: 主队列(专用队列) 主队列(主队列->主队列) 流(专用队列->主队列) 这种安排使流处理远离主线程。该应用程序通常每秒或每秒接收10-150条消息。流上下文的保存发生在每条消息解构和持久化之后。A6级设备的CPU使用率通常低于15% 然而,我的问题是记忆力。若我将一个NSFetchedResultsController连接到主上下文,我会在消
- 主队列(专用队列)
- 主队列(主队列->主队列)
- 流(专用队列->主队列)
如果您有任何想法,我们将不胜感激。我建议您使用与主上下文相同的持久存储协调器配置流上下文。并且可能会定期重置流上下文 在当前配置流上下文中,fill会对其父级施加额外的压力。如果在流上下文中发生重大更新,这种压力就会变得更加明显 首先,当流上下文需要执行某些需要锁定的操作时,它将锁定双亲 第二,当在流上下文中进行保存时,所有更改都被推回到父上下文,即主上下文。而你无法控制它。如果主上下文中有一个获取的结果控制器,则在保存时,它将逐个重播所有更改。如果更新量很大,则会带来很大的开销。肯定在CPU中,可能在内存中 我认为在后台处理大更新和刷新UI(特别是使用fetched results controller)的最佳模式是配置直接使用持久存储协调器进行大更新的上下文。然后,当发生重大更新时,只需在UI上下文中重新蚀刻即可。并且不要忘记将fetch请求上的fetch批处理大小设置为对您的案例值有意义的大小。您可以从屏幕上可见的单元格数量开始 这种模式效率更高,但会带来复杂性和成本。您需要考虑如何在其他上下文中刷新数据。您需要注意这一点,因为核心数据不会触及完全实现的对象。(设置
setShouldRefreshRefetchedObjects
也没有帮助,因为Apple向我确认了这个bug。)
例如,您在主上下文中获取某个对象,访问其属性以在屏幕上显示它。这个物体不再是一个缺陷了。然后,流上下文(现在直接配置了持久存储协调器)更新了相同的属性。即使在主上下文中重新蚀刻,并且对象将出现在搜索结果中,对象属性也不会更新
所以你可以用这样的东西:
- (void)refreshObjectsOnContextDidSaveNotification:(NSNotification *)notification {
NSSet *updatedObjects = notification.userInfo[NSUpdatedObjectsKey];
NSSet *updatedObjectIDs = [updatedObjects valueForKey:@"objectID"];
[self.mainContext performBlock:^{
for (NSManagedObject *object in [self.mainContext registeredObjects]) {
if (![object isFault] && [updatedObjectIDs containsObject:[object objectID]]) {
[self.mainContext refreshObject:object mergeChanges:YES];
}
}
}];
[self.masterContext performBlock:^{
for (NSManagedObject *object in [self.masterContext registeredObjects]) {
if (![object isFault] && [updatedObjectIDs containsObject:[object objectID]]) {
[self.masterContext refreshObject:object mergeChanges:YES];
}
}
}];
}
这将刷新主上下文和主上下文中更新的对象
当流上下文中的保存不是很大时,您可以使用标准的合并方法将更改合并到其他两个上下文中。当使用“获取结果控制器”时,您将能够在对象删除和插入时看到漂亮的单元动画。可以从上下文did save通知中的用户信息的NSInsertedObjectsKey
、nsUpdate-ObjectSkey
和NSDeletedObjectsKey
键获取的保存中受影响的对象数
在每次大保存之后,您可以重置流上下文。只是不要忘记,重置后,您无法在此上下文中访问任何以前获取的对象。您是否阅读过(包括有关插入对象的注释)?