我想了解和修复我的应用程序效率低下。
我的算法是:
fetch object collection from network
for each object:
if (corresponding locally stored object not found): -- A
create object
if (a nested related object locally not found): -- B
create a related object
我正在通过使用属于我的模式的相关对象的键创建谓词查询来检查 A 和 B 行。我看到 A(总是)和 B(如果执行分支到该部分)都会生成一个 SQL 选择,例如:
2010-02-05 01:57:51.092 app[393:207] CoreData: sql: SELECT <a bunch of fields> FROM ZTABLE1 t0 WHERE t0.ZID = ?
2010-02-05 01:57:51.097 app[393:207] CoreData: annotation: sql connection fetch time: 0.0046s
2010-02-05 01:57:51.100 app[393:207] CoreData: annotation: total fetch execution time: 0.0074s for 0 rows.
2010-02-05 01:57:51.125 app[393:207] CoreData: sql: SELECT <a bunch of fields> FROM ZTABLE2 t0 WHERE t0.ZID = ?
2010-02-05 01:57:51.129 app[393:207] CoreData: annotation: sql connection fetch time: 0.0040s
2010-02-05 01:57:51.132 app[393:207] CoreData: annotation: total fetch execution time: 0.0071s for 0 rows.
0.0071s 的查询在 3GS 设备上是可以的,但如果你将其中的 100 个加起来,你就会得到一个 700ms 的拦截器。
在我的代码中,我使用了一个助手来进行这些获取:
- (MyObject *) myObjectById:(NSNumber *)myObjectId {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[self objectEntity]]; // my entity cache
[fetchRequest setPredicate:[self objectPredicateById:objectId]]; // predicate cache
NSError *error = nil;
NSArray *fetchedObjects = [moc executeFetchRequest:fetchRequest error:&error];
if ([fetchedObjects count] == 1) {
[fetchRequest release];
return [fetchedObjects objectAtIndex:0];
}
[fetchRequest release];
return nil;
}
MyObject *obj = [self myObjectById];
if (!obj) {
// [NSEntityDescription insertNewObjectForEntityForName: ... etc
}
我觉得这是错误的,我应该以其他方式进行检查。它应该只访问数据库一次,然后应该从内存中获取,对吗?(即使对于我确定在本地存在并且应该已经通过以前的查询加载到内存中的对象,SQL 也会执行。)但是,如果我只有来自外部源的 myObjectId,这是我能想到的最好的。
所以,也许问题是:如果我有 myObjectId(MyObject 上的 Core Data int64 属性),我应该如何正确检查 CD 存储中是否存在相关的本地对象?预加载整组可能的匹配,然后断言一个本地数组?
(一种可能的解决方案是将其移至后台线程。这很好,除了当我从线程获取更改并执行 [moc mergeChangesFromContextDidSaveNotification:aNotification]; (通过通知从后台线程获取更改的对象)时,这仍然阻塞。)