3

我是第一次在这一轮发帖,所以如果我没有正确遵守所有规则,请多多包涵。

我正在为 iPhone (OS 3.1) 编写一个应用程序,并试图编写一些代码来添加小数。我有一个名为 SimpleItem 的核心数据实体,它有一个数量属性。这是我写的测试用例:

// Create and configure objects
    SimpleItem *si1 = [self createSimpleItem:@"si1"];
    si1.amount = [NSDecimalNumber decimalNumberWithMantissa:1000 exponent:0 isNegative:NO];
    SimpleItem *si2 = [self createSimpleItem:@"s12"];
    si2.amount = [NSDecimalNumber decimalNumberWithMantissa:2000 exponent:0 isNegative:NO];
    // Need to save prior to fetching results with NSDictionaryResultType (known limitation)
    [self save]; 

    // Describe fetch request
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"SimpleItem" inManagedObjectContext:self.context];
    [request setEntity:entityDescription];
    [request setResultType:NSDictionaryResultType];

    NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"amount"];
//  For whatever reason, evaluating this expression here is absolutely not working. Probably decimals aren't handled properly.
    NSExpression *sumAmountExpression = [NSExpression 
                                         expressionForFunction:@"max:"
                                         arguments:[NSArray arrayWithObject:keyPathExpression]];

    NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
    [expressionDescription setName:@"amount"];
    [expressionDescription setExpression:sumAmountExpression];
    [expressionDescription setExpressionResultType:NSDecimalAttributeType];
    [request setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]];

    // Fetch the amounts
    NSError *error = nil;
    NSArray *array = [self.context executeFetchRequest:request error:&error];

如果我通过 otest 执行此代码并对其进行调试,则在执行 fetch 请求时会出现异常:“-[NSDecimalNumber count]: unrecognized selector sent to instance.”

不过,仅在没有聚合函数的情况下评估 keyPathExpression 就可以正常工作。

参考文档显示了完全相同的示例,所以我想知道我做错了什么。或者这可能只是一个错误?

一切顺利,哈拉尔

4

3 回答 3

0

我想我以前遇到过这个问题。IIRC,问题是您已将获取结果类型设置为,NSDictionaryResultType但您在NSArray. 尝试切换NSManagedObjectResultType返回数组的获取结果类型。文档中的所有示例都使用默认的NSManagedObjectResultType.

在任何情况下,错误消息显然是由于 NSDecimal 对象被发送到数组的count消息。您可以通过将结果捕获在id. 例如:

id *genericObj = [self.context executeFetchRequest:request error:&error];  
NSLog("returned object=%@",genericObj);
NSLog("returned object class=%@",[genericObj class]);
于 2009-11-08T16:29:16.753 回答
0

谢谢你让我知道。问题是我实际上不想使用托管对象。毕竟,我只对数量感兴趣,这就是我从字典中得到的。

此外,尝试调查您所描述的问题并没有奏效,因为执行 fetch 请求立即失败,我没有得到任何回报。

还有其他想法吗?是否有任何其他可能获得汇总值?任何“最佳实践”?目前我执行以下操作(继续上面的代码):

NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; [表达式描述 setName:@"amount"]; [表达式描述 setExpression:keyPathExpression]; [表达式描述 setExpressionResultType:NSDecimalAttributeType]; [请求 setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]];

// Fetch the amounts
NSError *error = nil;
NSArray *array = [self.context executeFetchRequest:request error:&error];
if (array == nil) {
    STFail(@"Fetch request could not be completed: %@", [error localizedDescription]);
}
STAssertEquals([array count], (NSUInteger) 2, @"Number of fetched objects != 2");

// Manually calculate the sum
NSDecimalNumber *sum = nil;
for (NSDictionary * dictionary in array) {
    NSDecimalNumber *amount = (NSDecimalNumber *) [dictionary valueForKey:@"amount"];
    if (!sum) {
        sum = amount;
    } else {
        sum = [sum decimalNumberByAdding:amount];
    }
}
STAssertNotNil(sum, @"Sum is nil");
STAssertTrue([sum isEqualToNumber:[NSDecimalNumber decimalNumberWithMantissa:3000 exponent:0 isNegative:NO]], 
               @"Sum != 3000: %@", sum);

问候,哈拉尔

于 2009-11-10T00:18:22.173 回答
0

将您给定的源代码复制到一个新的 iPhone 项目并在模拟器中运行它在这里工作得很好。我在 Snow Leopard 上针对 3.1.2 SDK 进行编译。

这是我用于数据模型的:

型号说明 http://homepage.mac.com/aclark78/.Public/Pictures/test%20model.png

一定有其他原因导致您的问题。你能描述你的模型或进一步简化它吗?

于 2010-01-14T03:18:27.260 回答