>我有以下方法,该方法在 FOR 循环中调用并调用多次,每次遍历 NSDictionary 对象以创建和设置注释对象:
- (BOOL)updateById:(NSString *)entityId
withData:(NSDictionary *)dataDictionary {
DLog(@"Updating %@", [_entityClass description]);
if (_entityIdentifier == nil) {
DLog(@"entityIdentifier has not been set");
}
NSManagedObjectContext *context = ContextForThread;
id note = [_entityClass findFirstByAttribute:_entityIdentifier
withValue:entityId
inContext:context]; //This is running slowly ?
[note setValuesFromDictionary:dataDictionary];
BOOL changes = YES;
if ([note changedValues].count == 0) {
changes = NO;
DLog(@"Has NOT changed - Dont save");
}
else {
DLog(@"Has changed");
}
return changes;
}
我正在尝试优化此代码,并注意到findFirstByAttribute方法似乎相当慢。无论如何我可以优化这种方法吗?
从根本上说,问题是你正在做很多抓取,而很多抓取意味着很多工作。您在此处的目标应该是减少获取次数,最有可能的是一次性完成所有提取,然后重构代码以使用结果。例如,如果事先知道entityId
值:
-
使用已知的
entityId
值获取所有实例。我不知道MR是否有捷径。直接使用核心数据,您可以像下面这样进行获取。获取的结果将是_entityIdentifier
的值位于entityIds
数组中的所有实例:NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K in %@", _entityIdentifier, entityIds); NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey: _entityIdentifier ascending:YES];
-
重构上面的方法,以便传入托管对象和要分配给该对象的值字典。
还有其他方法可以解决这个问题,但无论如何,您应该一次获取多个对象,而不是为每个对象单独获取。
设置要编制索引的属性应该会有所帮助。除此之外,如果您经常调用此方法,请考虑执行批处理更新。您可以使用MR_findAllWithPredicate进行单个数据库查询,并为每个检索到的对象进行更新值。