优化核心数据/魔法记录 - findFirstByAttribute - 核心数据

时间:2013-10-01 15:01:27

标签: ios objective-c core-data optimization magicalrecord

我有一个在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方法似乎相当慢。无论如何我可以优化这种方法吗?

2 个答案:

答案 0 :(得分:2)

从根本上说,问题在于你做了大量的提取,很多提取意味着很多工作。您的目标应该是减少提取次数,最有可能的方法是一次性完成所有操作,然后重构代码以使用结果。例如,如果事先知道entityId值:

  1. 使用已知的entityId值获取所有实例。我不知道MR是否有这样的捷径。直接使用Core Data,你会得到类似以下内容的fetch。获取的结果将是_entityIdentifier数组中entityIds的值的所有实例:

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K in %@", _entityIdentifier, entityIds);
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey: _entityIdentifier ascending:YES];
    
  2. 重构上面的方法,以便传入托管对象和要分配给该对象的值字典。

  3. 还有其他方法可以解决这个问题,但不管怎样,你应该同时获取多个对象,而不是为每个对象进行单独的提取。

答案 1 :(得分:1)

设置要编制索引的属性应该有所帮助。 除此之外,如果您经常调用此方法,请考虑进行批量更新。 您可以使用MR_findAllWithPredicate为每个检索到的对象创建单个数据库查询和更新值。