- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个应用程序不断从 TCP/IP 端点接收 XML 消息流。收到每条消息后,应用程序将其内容消化到一组核心数据实体中。这是通过三个上下文结构实现的:
这种安排使流处理远离主线程。应用程序通常每秒或每两秒接收 10 - 150 条消息。 Stream 上下文的保存发生在每条消息被解构和持久化之后。 A6 级别设备上的 CPU 使用率通常低于 15%。
然而,我的问题是内存。如果我将 NSFetchedResultsController 连接到 Main 上下文,我会在消息到达时得到很好的消息流。但是,如果我进行概要分析,我会注意到我的 NSManagedObject 计数逐渐增加。最终内存压力将导致应用程序终止。
经过 12 分钟的分析,该应用已使用了 6300 条 XML 消息并解析了 121,000 个属性。属性占用 7.8MB,消息占用 438KB,应用程序总大小现在为 54MB。显然,这是不可持续的。
仪器注意到所有对象仍然存在。在互联网上闲逛让我相信我可能有一个保留周期导致对象没有错误。但是,使用“refreshObject”的建议在此处适用的文档中并不清楚。
收到 XML 后,将创建消息实体。接下来,使用 XML 的根节点作为名称和相关位来创建类型实体。类似地,对于每个元素和这些元素的子元素以及 XML 的任何内联属性,都会创建一个属性元素。这是有趣的部分,因为它具有对消息的引用(用于所有属性的平面表示)以及与自身的分层 childProperties 关系。在此过程结束时,上下文将被保存,主上下文将其拾取,FRC 将显示新行。
一个想法是在每保存数百条消息后重置 Stream 上下文。如果我断开 FRC,我基本上可以保持水平 - 但是当我重新连接 FRC 时,这感觉不对并且不能解决问题。
如有任何想法,我们将不胜感激。
最佳答案
我建议使用与主上下文相同的持久存储协调器配置您的流上下文。并且可能会定期重置流上下文。
在当前配置中,Stream context fill 给它的父级带来了额外的压力。如果 Stream 上下文中发生重大更新,这种压力就会变得更加明显。
首先,当 Stream 上下文需要做一些需要锁定的事情时,它会锁定两个父级。
其次,当在 Stream 上下文中发生保存时,所有更改都会被推回父级,即 Main 上下文。你无法控制它。如果 Main 上下文中有一个 fetched results controller,那么在保存时它将逐个重放所有更改。而且如果更新量很大,会带来很大的开销。肯定在 CPU 中,也可能在内存中。
我认为在后台处理大更新和刷新 UI(尤其是使用获取结果 Controller )的最佳模式是配置直接使用持久存储协调器进行大更新的上下文。然后,当发生大更新时,只需在 UI 上下文中重新获取。并且不要忘记将提取请求的提取批量大小设置为对您的案例值有意义的值。您可以从屏幕上可见的单元格数量开始。
此模式效率更高,但会带来复杂性成本。您需要考虑如何在其他上下文中刷新数据。你需要注意这一点,因为 Core Data 不接触完全实现的对象。 (设置 setShouldRefreshRefetchedObjects
也无济于事,因为 Apple 向我确认了这个错误。)
例如,您在 Main 上下文中获取了一些对象,访问了它的属性以便在屏幕上显示它。该对象不再是故障。然后您的 Stream 上下文(现在直接配置了持久存储协调器)更新了相同的属性。即使您在 Main 上下文中重新获取并且对象将出现在搜索结果中,对象属性也不会更新。
所以你可以使用这样的东西:
- (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];
}
}
}];
}
这将刷新主上下文和主上下文中的更新对象。
当 Stream 上下文中的保存量不大时,您可以使用标准合并方法简单地将更改合并到其他两个上下文中。当使用 fetched results controller 时,你将能够在对象删除和插入时看到漂亮的单元格动画。您可以从 context-did- 中用户信息的 NSInsertedObjectsKey
、NSUpdatedObjectsKey
和 NSDeletedObjectsKey
键获取保存中受影响的对象数保存通知。
在每次大保存之后,您都可以重置 Stream 上下文。只是不要忘记,重置后您无法在此上下文中访问任何先前获取的对象。
关于ios - 随着时间的推移,有问题的 NSManagedObject 积累,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21372607/
我自学了 Obj-C,并且一直在自学 Cocoa,但是将 Core Data 添加到我的程序中却让我非常头疼,因为我需要大量的自定义逻辑。以下是几个让我抓狂的问题。 如果我希望一个托管对象拥有另一个托
我正在创建一个新的 NSManagedObject 并尝试与另一个 NSManagedObject 建立关系,但收到此错误: Illegal attempt to establish a relati
我有一个 NSManagedObject 派生类 OrderMO,它具有 NSDate 类型的属性 OrderDate。我希望 OrderDate 的默认值是尚无关联订单的第一个月的第一个星期一。 为
我正在尝试使用我在该网站上找到的一个与使用 TableView 中的滑动功能从核心数据中删除相关的功能,但我无法弄清楚此错误消息需要我做什么?有人可以帮忙解决这个错误吗? import UIKit i
我正在创建一个名为“translation”的新 NSManagedObject。在翻译中,我需要创建两个额外的 NSManagedObjects 称为“phrase”。有时,其中一个短语分配会引发错
到目前为止,我已经在这个问题上花费了 6 个多小时,确实需要帮助。我编译的 RKCatalog 示例很好。但是当我尝试将示例包含到我的独立项目中时,我遇到了各种问题: 当我从我的主项目运行这个例子时,
我已经将一个 NSManagedObject 对象复制到一个临时的 NSManagedObject 对象中。这样,如果用户输入没有变化,我就可以使用那个临时的 NSManagedObject 对象。否
我正在使用 CoreData 开发 Objective-C,但出现以下错误... *** Terminating app due to uncaught exception 'NSInvalidArg
我正在为我的 iPhone 应用程序使用核心数据模型。我一直在寻找一种在 ManagedObjectContext 之外实例化或使用实体的方法。 (我知道这是不应该做的,我也更多地寻找一种不这样做的方
我正在与 CoreData 作斗争。我想获取以下对象: @interface Email : NSManagedObject { } @property (nonatomic, copy) NSStr
是否可以使用 NSFetchedResultsController 设置一个 UITableView,因为它是 dataSource,其中 Contact Group 决定了部分, Contact G
我正在尝试将对象添加到“一对一”关系中: //1. I create the temporary object for the ServerUpdates entity NSManagedObject
我有一个作者实体。 Author 实体在其 Class 定义中具有一组 Book 实体作为 1:many 关系。 Author 目前不在 managedObjectContext 中。 当我说 [se
这个问题已经存在: Must have a valid NSEntityDescription Objective c? 4年前关闭。 我在核心数据 x code8.3 中遇到错误,数据库已添加 DB
我想观察特定 NSManagedObject 的变化并相应地更新 UI。 我不想保留对NSManagedObject 的引用,因为它可能随时被删除(即通过远程推送通知的结果)。 目前我正在设置 NSF
我正在使用核心数据在 vc1 中保存一个类别,并想将列表属性添加到 vc2 中的列表中。我的数据模型是许多列表属性的一个类别。 我在 vc1 中添加这样的类别: func createNewCateg
我已将 RestKit 链接到一个 xcode 4 项目中,如 GitHub 安装页面所述,但在尝试构建时遇到此错误。有谁知道发生了什么事?我也在 RestKit IRC channel 上提问,正在
首先让我确保我有 X-Code 4.3.2 版本和 iOS 5.1 SDK。我在我的项目中使用以下方法进行核心数据操作。两种方法都会发出相同的警告。即“从结果类型为“NSManagedObject ”
我为我的 Story 模型创建了 NSManagedObject 的子类。我创建了几个新故事,如下所示: Story *newStory = [NSEntityDescription insertNe
我正在努力使我的 NSMangedObjectClass 配置文件可导出/可导出。 我试试this way 如果我在 NSArrays 中写入关系,则导出工作正常,因为 NSSet 没有 writeT
我是一名优秀的程序员,十分优秀!