我有两个实体Drink和Breweries。我在Json中有数据,我正在为每个人建立核心数据表,并建立了一个关系(从饮料到啤酒厂的一对一)。然而,试图在构建饮料对象时设置它显然会大大减慢这个过程,因为我每次创建一个新的饮料时都必须查询核心数据(有几千种饮料和大约1000家啤酒厂)。目前,啤酒厂有一个唯一的id与饮料上的属性相匹配。要做到这一点而又不会大大减慢加载时间,最好的方法是什么?我正在考虑只使用一个实体来代替,并将啤酒厂放在同一个表中,尽管这是糟糕的DB实践。
下面是从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;
// }
}];发布于 2014-06-01 08:07:09
每次迭代jsonCategories元素时都会重新获取酿酒厂列表。这会增加巨大的开销并导致速度变慢,而且这是不必要的,因为我假设列表不会改变。
更好的设计是获取它一次,然后根据需要进行过滤。我省略了下面的一些代码,只写了重要的部分,你应该能够自己填充它。
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-s。然后,只获取这些啤酒厂,然后再次迭代饮料结果以将啤酒厂添加到饮料中。这应该是这样的
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;
}嗯。我现在需要一杯啤酒。
https://stackoverflow.com/questions/23975509
复制相似问题