2016-07-04 10 views
0

ユーザーがページを更新するたびに、大量のデータをJSON形式(2000個以上のエンティティ)でCore Dataにロードしています。私が今やっていることはうまくいくが時間がかかるだけだ。何らかの種類のページネゴシエーションを検討していましたが、バックエンドの変更が必要です。うまくいけば誰かがプロセスを最適化するのを助けてくれることを願っていますまたは、iOSに大量のデータを保存する別のソリューションを教えてください。ここで大量のデータをコアデータに保存する

は、ほとんどの時間を要する部分である:

[moc performBlock:^{ 
    for (NSDictionary *dictionary in dataObjectsArray) { 
     NSPredicate *predicate = [ObjectA predicateWithDictionary:dictionary]; 
     NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:ENTITY_NAME]; 
     request.predicate = predicate; 

     NSError *error; 
     NSArray *fetchedObjects = [moc executeFetchRequest:request 
                error:&error]; 
     ObjectA *objectATemp = (ObjectA *)[fetchedObjects lastObject]; 
     if (!objectATemp) { 
      NSEntityDescription *entityDescription = [NSEntityDescription entityForName:ENTITY_NAME 
                   inManagedObjectContext:moc]; 
      objectATemp = [[ObjectA alloc] initWithEntity:entityDescription 
          insertIntoManagedObjectContext:moc]; 
     } 

     [ObjectA setObjectA:objectATemp 
       dictionary:dictionary]; 

     // check if user already liked the ObjectA 
     ObjectB *likedObject = [ObjectB objectBWithId:objectATemp.id]; 
     if (likedObject && 
      !objectATemp.user_liked.boolValue) { 
      [likedObject.managedObjectContext deleteObject:likedObject]; 
     } 
    } 

    NSError *error; 
    if ([moc hasChanges] && 
     ![moc save:&error]) { 
     NSLog(@"%@", error); 
    } 

    // saving Context 
    NSManagedObjectContext *managedObjectContext = [self newManagedObjectContext]; 
    [managedObjectContext performBlock:^{ 
     NSError *error; 
     if ([managedObjectContext hasChanges] && 
      ![managedObjectContext save:&error]) { 
      NSLog(@"%@", error); 
     } 

     if (completionHandler) { 
      completionHandler(); 
     } 
    }]; 
}]; 

任意のアドバイスは喜んでいます。

+1

何も変更されていない場合でも、エントリの削除や作成を回避できる方法はありますか?現在の情報をメモリに保持して新しい情報を比較し、変更をコアデータにのみ保存できますか?メモリ操作でははるかに高速になります。 – Paulw11

+0

コアデータを使用して大量のデータを格納することは問題ありません。 **多くの新しいデータを保存する**ユーザーがボタンをタップするたびに**は遅くなります。 ** ** ** **すべての**そのデータの読み込みを避けることができるいくつかの方法はありますか? –

答えて

0

同時にすべての2000が表示されない場合は、最初に100または200個のエンティティをダウンロードしてユーザーに表示し、残りのエンティティをバックグラウンドでダウンロードできます。もう1つの方法は、あなたが言ったように、バックエンドでページ分割を使用することです。

3

Core Dataで多くのデータを格納することは問題にはなりません。 2000年の記録は "あまり"ではない。ユーザーがボタンをタップするたびにたくさんの新しいデータを保存することは遅くなるでしょう。最高の解決策は、すべてこのデータの時間を格納する必要はありません。

しかし、コードにはかなりの非効率性もあります。

ループを通過するたびにフェッチ要求を行います。 dataObjectsArrayに2000個のオブジェクトが含まれていると仮定すると、2000個のフェッチです。それは簡単にデータを取得する最も効率的な方法です。 1回のフェッチを行うことができれば、あるいは2000回のパスごとに1回ではなく、一度に100または200のオブジェクトをフェッチすることができれば、大きな改善が得られます。あなたの述語やコード化するメソッドを記述していないので、これを行うのが最善の方法を教えるのは難しいですが、これが最初にやるべきことです。小さな塊でデータを取得できない場合は、で、それ以上は大きなもので処理できます。 setObjectA:dictionary:,objectBWithID:などのメソッドを変更する必要があるかもしれません。

また、ループの実行ごとにオブジェクトの一部が同じであることがあります。オブジェクトが毎回同じであれば、(潜在的に)2000回ではなく1回作成してください。たとえば、entityDescriptionです。これは何千ものフェッチ要求よりもはるかに問題にはなりませんが、いくらか改善されるはずです。

+0

これらのことを指摘していただきありがとうございます。私は間違いなくメカニズムを取り出すことから始まるものに取り組むでしょう。 – user1139921

関連する問題