コア データ データベースに cca 100 000 レコードを挿入しています。データベースには 3 つのエンティティが含まれています。Player、Club、PlayerClub エンティティの関係は次のとおりです: Player<-->>PlayerClub<<-->Club PlayerClub への挿入中に、約 50,000 レコードが挿入された後、大量のメモリ消費と速度の低下に気付きました。PlayerClub には一意の値しかないため、レコードが更新されることはありません。テスト上の理由から、Player テーブルと Club テーブルを空にして、プログラムを再度実行しました。速度の低下はありませんでしたが、メモリの消費量が再び膨大になりました。これはコードです:
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:ap.persistentStoreCoordinator];
[context setUndoManager:nil];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"PlayerClub"
inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
NSEntityDescription *entityKlubovi = [NSEntityDescription entityForName:@"Club" inManagedObjectContext:context];
NSFetchRequest *requestKlubovi = [[NSFetchRequest alloc] init];
[requestKlubovi setEntity:entityKlubovi];
[requestKlubovi setFetchLimit:1];
NSEntityDescription *entityIgraci = [NSEntityDescription entityForName:@"Player" inManagedObjectContext:context];
NSFetchRequest *requestIgraci = [[NSFetchRequest alloc] init];
[requestIgraci setFetchLimit:1];
[requestIgraci setEntity:entityIgraci];
for (int i=0; i<[parsedKlubIgraci count]; i++) {
@autoreleasepool {
KlubIgrac *klubIgrac = [[KlubIgrac alloc] initWithEntity:entity insertIntoManagedObjectContext:context];
klubIgrac.iD = p.id;
//... add some othe properties
variables = [NSDictionary dictionaryWithObject:p.igracID forKey:@"ID"];
localPredicate = [predicateIgraci predicateWithSubstitutionVariables:variables];
[requestIgraci setPredicate:localPredicate];
klubIgrac.igrac = [self DohvatiIgracZaIgracId:p.igracID cntx:context request:requestIgraci predicate:localPredicate];
variables = [NSDictionary dictionaryWithObject:p.klubID forKey:@"ID"];
localPredicate = [predicateKlubovi predicateWithSubstitutionVariables:variables];
[requestKlubovi setPredicate:localPredicate];
klubIgrac.klub = [self DohvatiKlubZaKlubId:p.klubID cntx:context request:requestKlubovi predicate:localPredicate];
}
}
+(Club *)DohvatiKlubZaKlubId:(int)klubid cntx:(NSManagedObjectContext *)context
request:(NSFetchRequest *)request predicate:(NSPredicate *)predicate
{
@autoreleasepool {
NSError *error;
NSArray *arTmp;
arTmp = [context executeFetchRequest:request error:&error];
Club *klub;
if(arTmp != nil && [arTmp count]){
return [arTmp objectAtIndex:0];
}
}
}
DohvatiIgracZaIgracId メソッドは基本的に DohvatiKlubZaKlubId と同じメソッドなので載せません。このコードは約 100 000 回呼び出されます。以前のメモリ消費量は約 150 MB です。650 MB が終了した後。そのため、コンテキストを保存せず、データベースから何も取得せずに 500 MB を消費すると、テーブルが空になります。コメントしたら
arTmp = [context executeFetchRequest:request error:&error];
DohvatiIgracZaIgracId および DohvatiKlubZaKlubId メソッドの行を変更すると、メモリ消費量が 200 MB に減少します。したがって、何もしないコード行の差は 400MB です。これはできません。誰にでもアイデアはあります。しばらくすると、アプリが 2.5 GB を超えて消費します。
測定はシミュレーターで行われたため、後でプリロードするデータベースを構築する必要があるため、速度が重要です:) ...事前にThx