Jaa*_*nus 5 iphone performance core-data nsfetchrequest cocoa-design-patterns
我的应用程序效率低下,我想了解并修复.
我的算法是:
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
Run Code Online (Sandbox Code Playgroud)
我正在通过使用相关对象的键创建谓词查询来检查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.
Run Code Online (Sandbox Code Playgroud)
一个查询的0.0071s在3GS设备上很好,但如果你添加其中的100个,你只需要一个700毫秒的阻止程序.
在我的代码中,我正在使用帮助程序来执行这些提取:
- (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
}
Run Code Online (Sandbox Code Playgroud)
我觉得这是错的,我应该以其他方式进行检查.它应该只打一次数据库,之后应该来自内存,对吧?(即使对于我知道肯定存在于本地的对象也会执行SQL,并且应该已经使用先前的查询加载到内存中.)但是,如果我只有来自外部源的myObjectId,这是我能想到的最好的.
所以,也许问题是:如果我有MyObjectId(MyObject上的Core Data int64属性),我该如何正确检查CD存储中是否存在相关的本地对象?预加载整组可能的匹配,然后谓词本地数组?
(一种可能的解决方案是将其转移到后台线程.这没关系,除非我从线程获得更改并执行[moc mergeChangesFromContextDidSaveNotification:aNotification];(通过通知从后台线程获取更改的对象),这仍然阻止.)
阅读"核心数据编程指南"中的"有效实现查找或创建".
基本上,您需要创建一个ID或属性数组,如名称,或者您从托管对象实体中获得的任何内容.
然后,您需要创建一个谓词,该谓词将使用此数组过滤托管对象.
[fetchRequest setPredicate:[NSPredicate predicateWithFormat: @"(objectID IN %@)", objectIDs]];
Run Code Online (Sandbox Code Playgroud)
当然,"objectIDs"可以是您可以用来识别的任何东西.它不必是NSManagedObjectID.
然后,您可以执行一次获取请求,并迭代生成的获取对象,以查找重复项.如果它不存在,请添加一个新的.