2013-10-01 123 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陣列中的結果到那個對象。

還有其他方法可以解決這個問題,但是不管怎樣,您應該一次獲取多個對象,而不是爲每個對象執行一次單獨的獲取。