gpt4 book ai didi

ios - 核心数据后台保存性能问题

转载 作者:行者123 更新时间:2023-12-01 18:15:25 25 4
gpt4 key购买 nike

我编写了一个使用核心数据的应用程序,该数据通过wifi从传感器收集各种数据。我的数据线程在后台运行,从wifi读取套接字上的数据并创建新的核心数据实体。问题是我每秒大约要更新27次,当我尝试让线程在收到对象后立即调用对象的保存时,我的UI开始滞后并且程序变得无法使用,我不确定是否这是由于我的代码中存在设计缺陷或与Core Data工作方式的性质有关。

我想知道一些如何在不影响UI或任何其他应用程序代码的情况下主动在后台进行保存的选项。我曾想过也许有一种方法可以在另一个后台线程中每隔几秒钟触发一次保存500条记录的记录,但是我不确定a)如何实现这一目标,b)是否有可能。

我正在通过以下方式积极创建对象:
[NSEntityDescription insertNewObjectForEntityForName:@"RPYL" inManagedObjectContext:managedObjectContext];
一旦完成数据收集,我就会调用:
[managedObjectContext save:&error]

最佳答案

您不能在后台保存而不影响主线程-SQLite开发人员认为"Threads are evil. Avoid them."是过时的。因此,使用SQLite涉及很多互斥。保存时,无论存储来自何处,永久性存储都将被锁定。如果在此期间需要访问商店的其他任何内容,则必须等待。如果您有受影响的索引,则保存涉及将受影响的表中的每个项目都放入并根据索引列对它们进行排序,因为SQLite通过二进制搜索实现了索引。因此,成本可以是您要插入多少再加上商店中已有多少的函数。

首先,在将线程限制跳到主队列上时尝试进行智能故障处理-使用NSFetchRequest并明确表示您希望事前进行故障处理。然后,您无需访问商店就可以访问它们,从而免去了互斥锁的麻烦。尝试为您的目标设置-com.apple.CoreData.SQLDebug 1来运行,以查看您去商店的频率:如果不是针对您进行了优化的东西,那么我保证它将比您想像的多得多。

通用技巧也适用:如果要执行工作,则针对runloop进行调度,而不是直接针对主队列进行调度,而不是在用户与应用程序进行交互时进行调度。 Runloop会切换到跟踪模式和退出跟踪模式,因此您只需将工作安排为默认模式,它将自动避免在用户控制下UI繁忙时运行。

如果那不能解决问题,并且您的记录打算在收据时保持不变,而没有复杂的查询,则可以考虑使用Core Data作为永久存储,而是将自己设计的不变的非托管对象用于运行时使用。在后台构建这些对象,然后将它们向前传递。

编辑:批处理您的保存很容易-只是从字面上讲不要过于频繁地调用保存。一种解决方案是让BOOL指示是否安排了保存;当您要保存时,如果没有安排,请使用dispatch_after从现在开始安排一秒钟。如果已安排,则什么也不做。如果您不断有数据输入,那么比较复杂的方案(例如,我上次保存的时间,那么直到我可以再次保存之前要花多长时间?)不会为您带来很多好处。

关于ios - 核心数据后台保存性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22482008/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com