我有两个实体饮料和啤酒厂。我在Json中有数据,我正在为每个建立核心数据表,并建立了一个关系(饮料到啤酒厂一对一)。然而,尝试在构建Drink对象时设置它显然会大大减慢这个过程,因为每次创建一个新饮料时我都要查询核心数据(有几千个饮料和大约1000个啤酒厂)。目前,啤酒厂有一个与饮料属性相匹配的唯一ID。在不减慢加载时间的情况下,最好的方法是什么?我正在考虑只使用一个实体并将啤酒厂放在同一个表中,即使这是糟糕的数据库实践。
以下是从json构建饮料表的代码,其中添加了啤酒厂中添加的代码。
[jsonCategories enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
Drink *drink = [NSEntityDescription insertNewObjectForEntityForName:@"Drink" inManagedObjectContext:importContext];
//drinkType.id = [obj objectForKey:@"id"];
drink.name = [obj objectForKey:@"name"];
drink.alcoholByVolume = [obj objectForKey:@"abv"];
drink.drinkType = beerDrinkType;
drink.breweryId = [obj objectForKey:@"brewery_id"];
// NSArray *fetchedObjects;
// NSFetchRequest *fetch = [[NSFetchRequest alloc]init];
// NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Breweries" inManagedObjectContext:importContext];
// [fetch setEntity:entityDescription];
// [fetch setPredicate:[NSPredicate predicateWithFormat:@"id =%@", drink.breweryId]];
// NSError *errorBrewery;
// [fetch setFetchLimit:1];
// fetchedObjects = [importContext executeFetchRequest:fetch error:&errorBrewery];
// if (fetchedObjects && [fetchedObjects count] > 0){
// Breweries *fetchedBrewery = [fetchedObjects objectAtIndex:0];
// drink.breweries = fetchedBrewery;
// }
}];
答案 0 :(得分:0)
您正在使用jsonCategories元素的每次迭代重新获取brewery列表。这会增加巨大的开销并导致缓慢,并且是不必要的,因为我认为列表不会改变。
更好的设计是获取一次,然后根据需要对其进行过滤。我在下面省略了一些代码,只写了重要的部分,你应该能够自己填写。
NSFetchRequest *fetch = …;
// Note that predicate is not set here
fetchedBreweries = [importContext executeFetchRequest…];
[jsonCategories enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
…
NSArray *matchingBreweries = [fetchedBreweries filteredArrayUsingPredicate:…predicate];
drink.breweries = matchingBreweries.firstObject;
}];
也许这也会很慢,因为如果你拿到所有的啤酒厂,它可能会消耗太多的CPU和内存(虽然我先试着看看这是不是真的有问题)。
进一步优化可能是您首先遍历jsonCategories并创建一组在结果中找到的啤酒厂ID。然后,您只获取这些啤酒厂,然后再次重复饮料结果,将啤酒厂添加到饮料中。这就像是
NSMutableSet *breweryIds = [NSMutableSet set];
[jsonCategories enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
…
[breweryIds addObject:[obj objectForKey:@"brewery_id"]];
}];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
[fetch setPredicate:[NSPredicate predicateWithFormat:@"id in %@", breweryIds]];
NSArray *breweries = [importContext executeFetchRequest…]
for (Drink *drink in drinks) {
NSArray *matchingBreweries = [fetchedBreweries filteredArrayUsingPredicate:…predicate];
drink.breweries = matchingBreweries.firstObject;
}
嗯。我现在需要一杯啤酒。