我有一个iPad应用程序,如果它在屏幕上,它会连续记录手指位置(每秒最多30次),并为记录的每个数据集保存“样本”对象到核心数据。过了一会儿,也许两三分钟,这个过程或者至少用户的反馈变得非常慢。如果我关闭应用程序并重新启动它从一开始就很慢,但删除持久存储有助于使其恢复到原始性能。因此,我认为问题应该与数据存储有关。
我试图用时间分析器检测问题,但大部分时间都是由系统库和非Objective-C代码消耗的。如果我将其关闭以进行分析,那么最耗时的方法是初始化样本对象:
@implementation Sample (Create)
+(Sample *)sampleWithTime:(double)time
xValue:(double)x
yValue:(double)y
eventType:(EventType)event
chillStatus:(BOOL)chill
participant:(Participant *)whoListened
track:(Track *)whichTrack
inManagedObjectContext:(NSManagedObjectContext *)context
{
Sample *sample;
if (!sample) {
sample = [NSEntityDescription insertNewObjectForEntityForName:@"Sample" inManagedObjectContext:context];
sample.time = time;
sample.x = x;
sample.y = y;
sample.event = event;
sample.chillStatus = chill;
sample.whichTrack = whichTrack;
sample.whoListened = whoListened;
}
return sample;
}
sample.whichTrack =哪条曲目;设置与给定方法的track-object(ManagedObject子类,指的是正在播放的音乐)的关系。它是一对多的关系,因为每个样本只有一个轨道,但每个轨道有很多样本。这条线占用了整个方法的87%的时间,即使下一行完全正确同样的,与此相比几乎不需要任何东西。
这在这里搜索问题是否有意义?数据库可以变得那么慢,因为关系中的对象集变得更大,必须被复制才能添加对象或类似的东西吗?我能做些什么来提高性能吗?作为文件的数据库根本不会变大,它仍然不到1 MB。
答案 0 :(得分:1)
在那里搜索问题很有意义。
我假设您在whichTrack
对象上设置samples
(to-one)关系与反Track
(对多)关系。
你需要30 Sample
s / sec ==>同一Track
上的3分钟采样将保持:多对多关系中的5400个对象。这种关系在两端保持不变,这意味着无论何时插入新样本,都必须从商店中获取整个对象集(至少是它们的错误)(如果还没有出现故障)。
如果您在每个新Sample
之后保存并释放上下文(重置或刷新Track
对象),则下次访问{时,将需要重新获取多对多关系中的所有现有项目{1}}项目。
我会先尝试删除反向关系(Track
实体的多对侧)并查看其行为。
请注意,这将消除Track
删除(Track
个对象)后的任何级联。
如果您仍然需要在Sample
删除后进行级联,则可以通过向Track
实体添加prepareForDeletion
实施方案来自行添加。
另一个解决方案(更优雅)是将您的样本分成Track
个对象
SampleContainer
对象与Track
之间存在多对多的关系
每个容器将限于'N'个样本
填充容器后,将新容器添加到SampleContainer
。
除此之外:
您可以仅在每个'T'时间间隔执行保存。这将进一步减少商店访问(保存),但这可能不适合您,因为如果用户在两次保存之间终止应用程序(您可以在转到后台之前总是保存),您可能会松开Track
。