我有一个在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方法似乎相当慢。无论如何我可以优化这种方法吗?
答案 0 :(得分:2)
从根本上说,问题在于你做了大量的提取,很多提取意味着很多工作。您的目标应该是减少提取次数,最有可能的方法是一次性完成所有操作,然后重构代码以使用结果。例如,如果事先知道entityId
值:
使用已知的entityId
值获取所有实例。我不知道MR是否有这样的捷径。直接使用Core Data,你会得到类似以下内容的fetch。获取的结果将是_entityIdentifier
数组中entityIds
的值的所有实例:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K in %@", _entityIdentifier, entityIds);
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey: _entityIdentifier ascending:YES];
重构上面的方法,以便传入托管对象和要分配给该对象的值字典。
还有其他方法可以解决这个问题,但不管怎样,你应该同时获取多个对象,而不是为每个对象进行单独的提取。
答案 1 :(得分:1)
设置要编制索引的属性应该有所帮助。 除此之外,如果您经常调用此方法,请考虑进行批量更新。 您可以使用MR_findAllWithPredicate为每个检索到的对象创建单个数据库查询和更新值。