0

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 メソッドがかなり遅いようです。この方法を最適化できる方法はありますか?

4

2 に答える 2

2

基本的に、問題は大量のフェッチを行っていることであり、大量のフェッチは大量の作業を意味します。ここでの目標は、フェッチの数を減らすことです。ほとんどの場合、すべてを一度に実行してから、結果を使用するようにコードをリファクタリングします。たとえば、entityId値が事前にわかっている場合:

  1. 既知の値を使用してすべてのインスタンスをフェッチしますentityId。MR にショートカットがあるかどうかはわかりません。Core Data を直接使用すると、フェッチで次のようになります。フェッチの結果は、 の値が配列_entityIdentifier内にあるすべてのインスタンスになります。entityIds

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K in %@", _entityIdentifier, entityIds);
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey: _entityIdentifier ascending:YES];
    
  2. 上記のメソッドをリファクタリングして、管理対象オブジェクトと、そのオブジェクトに割り当てる値の辞書の両方を渡すようにします。

これにアプローチする方法は他にもありますが、何らかの方法で、オブジェクトごとに個別にフェッチするのではなく、一度に複数のオブジェクトをフェッチする必要があります。

于 2013-10-01T20:38:50.897 に答える
1

属性を索引付けするように設定すると、少し役立つはずです。それ以外に、このメソッドを頻繁に呼び出す場合は、バッチ更新を行うことを検討してください。MR_findAllWithPredicate を使用して、単一の DB クエリを作成し、取得した各オブジェクトの値を更新できます。

于 2013-10-01T19:11:20.250 に答える