2013-10-01 91 views
0

我有以下方法被称为在for循环内并且被调用多次,每次通过一个NSDictionary对象迭代创建和设置的注释对象:优化核心数据/神奇记录 - findFirstByAttribute - 核心数据

- (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

每当你在循环中调用这个方法时,'entityID'是否相同? –

+0

嗨汤姆 - 每次都不一样。 – GuybrushThreepwood

+0

还有一件事 - 你的问题说目的是“创建和设置一个音符对象”。但是你的代码似乎只是查找对象,而不是创建它们。你能澄清吗? –

回答

1

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

2

从根本上来说,问题在于您正在进行大量提取操作,而大量提取操作意味着大量工作。您的目标应该是减少抓取次数,最有可能的方法是一次完成所有操作,然后重构代码以使用结果。例如,如果entityId值被预先已知:

  1. 抓取使用已知entityId值的所有实例。我不知道MR是否有这个捷径。直接使用核心数据,您可以通过fetch获得如下内容。

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K in %@", _entityIdentifier, entityIds); 
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey: _entityIdentifier ascending:YES]; 
    
  2. 重构上面的方法,让你在这两个管理对象,你要分配值的字典经过:的获取将所有实例其中_entityIdentifier值是entityIds阵列中的结果到那个对象。

还有其他方法可以解决这个问题,但是不管怎样,您应该一次获取多个对象,而不是为每个对象执行一次单独的获取。