将数据对象加载到NSArray会导致启动缓慢

时间:2011-01-05 01:43:34

标签: iphone core-data

我有一个大约500个对象的Core Data数据库。这些对象是用户将查看和修改的“卡片”。当用户修改卡片时,名为“groupNumber”的属性将会更改。

每组中这些卡的顺序非常重要,由用户决定。我将数据库对象加载到一个数组中。当用户进行更改时,我使用'title'属性将数组的顺序保存到plist中。

重新启动应用程序时出现问题。我需要按照保存的顺序加载组数组。但是当我使用plist执行获取请求时,它的速度非常慢。

慢代码是:

// get array from plist sorted by 'title'
NSMutableArray *group1Temp = [plistData objectForKey:@"group1ArrayData"];

for (int i = 0; i < [group1Temp count]; i++) {
    // set predicate to 'title' attribute
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"title == %@", [group1Temp objectAtIndex:i]];

    // load filtered database object into temp array
    NSArray *temp = [self.vocabDeckArray filteredArrayUsingPredicate:predicate];

    [self.group1Array addObjectsFromArray:temp];
}

当执行500次时,它太慢了。如果我可以将数据库对象本身的NSArray保存到plist中,那么我就不需要进行谓词搜索,但似乎我不能这样做。

我认为我对此的整个方法都是错误的。如何以更快的方式保存/加载数据库对象数组的顺序?将数据库对象加载到数组本身是不是很糟糕?

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

遍历整个vocabDeckArray并为group1Temp中的每个对象过滤一次效率非常低。有许多方法可以在少于O(n ^ 2)的时间内重建此排序数据集。

一个简单的选项可能是存储一个字典,其中对象的标题为键,它们在数组中的位置为值。这样你就可以构造一个已知长度的数组,并将vocabDeckArray中的每个对象放入一个传递中的正确位置(从vocabDeckArray获取第一个对象,从group1Array中查找属于group1Array的位置字典,插入self.vocabDeckArray,继续下一个对象)。这仍然不是特别快,但它似乎是对你当前行为的微小改变。

另外考虑循环中方法调用的数量。 self.group1Array和{{1}}是您在循环的每次迭代中进行的方法调用,即使它们始终返回相同的对象。保持引用这些对象的局部变量可以节省每次迭代时2次方法调用的开销。