零件中的核心数据优化— 1

大多数时候,我们的应用程序都具有数据存储功能,例如缓存,提供脱机支持或提高应用程序性能等目的。 在本系列文章中,我们将探索一些设计技巧,并为提高iOS应用程序上的Core Data性能奠定基础。

这会导致iPad App的fps下降。 它不仅降低了fps速度,而且使我们的应用程序反复缓慢。 滚动tableview / collection视图确实很痛苦,因为App暂时停止了。

如果不运行Core Data工具,我将不会发现此问题。

规则1:测量,测量和测量

如果进行测量,您会发现板子前面有问题。 那么为什么不先这样做呢?

进行一些操作通常会导致我获取大量数据,因为我对记录中的每个项目都进行了重复的访存调用。 由于每个记录都可以使用其ID进行标识 您可以告诉CD根据ID一次获取所有记录。

 编号:[Int] 
让fetchRequest = NSFetchRequest (entityName:“ MyEntity”)
fetchRequest.predicate = NSPredicate(格式:“ id IN%@”,id)

虽然它减少了我的提取次数,但仍然没有帮助我减少保存 算是因为我在做这样的傻事:

 下载的记录中的ID { 
//在此更改托管对象的上下文并将其保存在context.perform {
做{
尝试context.save()
}将let错误捕获为NSError {
fatalError(“错误:\(error.localizedDescription)”)
}
}
}

由于Core Data将获取的对象保留在上下文中(在内存中),因此您可以修改存在于上下文中的获取的对象。 除非您清除上下文,否则上下文会保留MO的更改。 所以现在我们的代码看起来像:

 下载的记录中的ID { 
//在此处更改托管对象的上下文。
updateEntity()
//变更将在上下文中存在
}
  //现在保存上下文。 这会将更改从上下文推送到存储。 
context.perform {
做{
尝试context.save()
}将let错误捕获为NSError {
fatalError(“错误:\(error.localizedDescription)”)
}
}

这样节省了往返时间。 您将如何证明这一点? 返回规则1。

这将我引向下一条规则。

规则2:一次提取,批量保存

等等! 我们可以在这里做更多吗? 看起来像是。 虽然我只需要更新一些值(例如,人员的最后签入位置),但我不需要获取整个Person实体。 这增加了应用程序的内存占用。 通过将获取结果类型设置为字典和要获取的属性,可以在此处抢救核心数据。

fetchRequest.propertiesToFetch = ["attribute_name"] 
fetchRequest.resultType = .dictionaryResultType

一旦将其设置为活动状态,CD就会以键为attribute_name.返回字典数组attribute_name.

这将我引向下一条规则。

规则3:最低提取

不要过度拥挤或污染您的环境。

到目前为止一切顺利。 让我们为下一条规则做好准备。

我们有基于任务的应用程序,其中用户执行了每个任务都与创建任务的用户或团队相关联。 最后,如果要查看人员信息,可以签入人员详细信息。 代表人的实体的建模如下:-

我们要求显示用户信息及其图片。 我们从后端获取这些信息并将其存储在CD中。 虽然它解决了我们保留用户图片的目的,但以增加应用程序/受管对象上下文的内存占用为代价。 ( 尽管我们只需要缩略图,并且在用户单击时应显示一个大图像 )。

有关存储大型二进制数据的问题通常会根据业务规则或UI工作流采用两步方法。

步骤1:

利用将大型二进制数据存储到框架提供的外部文件中的优势。 您可以通过在数据模型中选中“允许外部存储”来设置此选项。

这样会将大文件(通常> 1mB)存储到外部文件中,不用担心,因为CD会为您管理这些文件。 此外,我们还将其应用于任务实体,该任务实体包含pdf,image和docs等附件。

第2步:

在我们的案例中,只有在用户想要查看时(通过单击缩略图),才能看到较大的用户图片,否则应用程序很好,仅显示缩略图。 这对我们来说是至关重要的线索,我们试图加以利用。 我们拆分模型并创建另一个实体“ I mage” 。 现在,我们的新实体具有已选中外部存储选项的属性图片 。 但是,我们还修改了Person实体以仅存储缩略图(在处理了来自实际图像的缩略图之后)

因此,现在我们仅在用户真正希望以全视图显示时加载图像。 这将我引向下一条规则。

规则4:明智地使用数据模型

从UI流程,业务规则中获取线索,并在模型中添加智慧。

谢谢!