我有以下 Coredata 模型:
Warengruppe
包含特定产品的名称,WarengruppeVK
是对 a 的处理Warengruppe
,它包含产品的售价和其他一些数值。PbsRow
描述了在某个时间范围内完成了多少WarengruppeVK
,例如 jahr=2012 和 monat=2 告诉我们产品在 2012 年 2 月被销售给特定客户的次数。
现在,我有一个表格视图,需要显示在某个定义的时间范围内每个特定产品获得了多少收入(用户可以定义开始和结束日期)。此外,我需要显示一年前在同一时间段内获得了多少收入。
所以,这就是我的做法:首先,我Warengruppe
从核心数据中获取所有对象(目前有 12 种产品)。然后,我在我的数组上使用 for 循环Warengruppe
并计算netto
每个的总和,WarengruppeVK
使用谓词 wherePbsRow
和设置为用户选择的时间范围。我这样定义 FetchRequest: NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"WarengruppeVK"];jahr
monat
NSExpression *keyPathExpressionNetto = [NSExpression expressionForKeyPath:@"netto"];
NSExpression *keyPathExpressionDB = [NSExpression expressionForKeyPath:@"db_basis"];
NSExpression *sumExpressionNetto = [NSExpression expressionForFunction:@"sum:" arguments:[NSArray arrayWithObject:keyPathExpressionNetto]];
NSExpression *sumExpressionDB = [NSExpression expressionForFunction:@"sum:" arguments:[NSArray arrayWithObject:keyPathExpressionDB]];
NSExpressionDescription *expressionDescriptionNetto = [[NSExpressionDescription alloc]init];
[expressionDescriptionNetto setName:@"sumnetto"];
[expressionDescriptionNetto setExpression:sumExpressionNetto];
[expressionDescriptionNetto setExpressionResultType:NSDecimalAttributeType];
NSExpressionDescription *expressionDescriptionDB = [[NSExpressionDescription alloc]init];
[expressionDescriptionDB setName:@"sumdb"];
[expressionDescriptionDB setExpression:sumExpressionDB];
[expressionDescriptionDB setExpressionResultType:NSDecimalAttributeType];
[request setPropertiesToFetch:[NSArray arrayWithObjects:expressionDescriptionNetto, expressionDescriptionDB, nil]];
[request setResultType:NSDictionaryResultType];
这是循环:
for (Warengruppe *wgruppe in warengruppen) {
//predicateVJ defines the Timeframe for PbsRow
productPredicateVJ = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:predicateVJ, [NSPredicate predicateWithFormat:@"warengruppe=%@",wgruppe],nil]];
[request setPredicate:productPredicateVJ];
NSArray *objectsVJ = [context executeFetchRequest:request error:&error];
float nettoVJ = [[[objectsVJ valueForKey:@"sumnetto"] firstObject] floatValue];
float dbVJ = [[[objectsVJ valueForKey:@"sumdb"] firstObject] floatValue];
float dgVJ = dbVJ/nettoVJ*100;
//Now doing the same for Timeframe minus 1 year (predicateJ)
productPredicateJ = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:predicateJ, [NSPredicate predicateWithFormat:@"warengruppe=%@",wgruppe],nil]];
[request setPredicate:productPredicateJ];
NSArray *objectsJ = [context executeFetchRequest:request error:&error];
float nettoJ = [[[objectsJ valueForKey:@"sumnetto"] firstObject] floatValue];
float dbJ = [[[objectsJ valueForKey:@"sumdb"] firstObject] floatValue];
float dgJ = dbJ/nettoJ*100;
}
现在的问题是,获取所有数据大约需要 14 秒。但是,如果我删除第二部分(以 // 对时间帧负 1 执行相同操作开始),则只需 7 秒。
所以我的问题是,是否有一些正确的方法可以将其分成 2 个线程?我已经用 2dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
个块尝试过这个,但由于某种原因,它只需要相同的时间(14 秒)。还是有其他方法可以改进此请求?我不能使用任何获取限制,因为我需要这些值的绝对总和。最大的问题是我正在使用的大量数据。这是一个必须离线工作的企业应用程序,所以我无法在某些服务器上计算这些东西并使用 http 将其传递给 iPad。
WarengruppeVK
现在有 328.666 行:-/。
提前致谢。
编辑:这是 iPad 上的一块全屏,计算完成后:
VJ 表示去年,IST 表示当前时间范围
编辑2:
predicateVJ
并predicateJ
像这样初始化(在本例中,选择的时间范围是当前月份):
NSPredicate *predicateVJ = [NSPredicate predicateWithFormat:@"(pbsrow.jahr=%d) AND (pbsrow.monat=%d)", year-1, month];
NSPredicate *predicateJ = [NSPredicate predicateWithFormat:@"(pbsrow.jahr=%d) AND (pbsrow.monat=%d)", year, month];
然后我在后台线程上开始获取请求:
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
NSArray *warengruppen = [[CoredataModelHolder sharedHolder] allWarenGruppen];
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:[(AppDelegate*)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator]];
NSPredicate *productPredicateVJ;
NSPredicate *productPredicateJ;
for (Warengruppe *wgruppe in warengruppen) {
//See 2nd snippet of my question.
}
});