2013-10-01 4 views
0

У меня есть следующий метод, который вызывается внутри для цикла и называется несколько раз, каждый раз повторяя через NSDictionary объекта для создания и установить ноту объекта:Оптимизация Core Data/Magical запись - findFirstByAttribute - Core Data

- (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 значения. Я не знаю, есть ли у МР для этого ярлык. Используя Core Data напрямую, вы можете сделать следующее с извлечением. Результаты выборки были бы все случаи, когда значение _entityIdentifier находится в entityIds массиве:

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K in %@", _entityIdentifier, entityIds); 
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey: _entityIdentifier ascending:YES]; 
    
  2. реорганизовать метод выше, так что вы передаете как управляемый объект и словарь значений, которые вы хотите назначить к этому объекту.

Есть и другие способы приблизиться к этому, но так или иначе вы должны использовать сразу несколько объектов, вместо того чтобы делать отдельную выборку для каждого из них.