0

我有以下 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"];jahrmonat

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: predicateVJpredicateJ像这样初始化(在本例中,选择的时间范围是当前月份):

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.
    }
});
4

0 回答 0