我第一次发帖到这一轮,所以如果我没有正确遵守所有规则,请耐心等待。
我正在为iPhone(OS 3.1)编写一个应用程序,我正在尝试编写一些允许我添加小数的代码。我有一个名为SimpleItem的Core Data实体,带有amount属性。这是我写的测试用例:
// 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执行此代码并对其进行调试,则在执行获取请求时会出现异常:“ - [NSDecimalNumber count]:无法识别的选择器发送到实例。”
只是在没有聚合函数的情况下评估keyPathExpression可以正常工作。
reference documentation显示完全相同的示例,所以我想知道我做错了什么。或者这可能只是一个错误?
一切顺利, 哈拉尔德
答案 0 :(得分: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]);
答案 1 :(得分:0)
谢谢你让我知道。问题是我实际上不想使用托管对象。毕竟,我只对数量感兴趣,这就是我用字典获得的。
此外,尝试调查您所描述的问题并不起作用,因为执行获取请求会立即失败,而且我没有得到任何回复。
还有其他想法吗?是否有其他可能获得总价值?任何“最佳实践”?目前我做了以下(继续上面的代码):
NSExpressionDescription * expressionDescription = [[NSExpressionDescription alloc] init]; [expressionDescription setName:@“amount”]; [expressionDescription setExpression:keyPathExpression]; [expressionDescription setExpressionResultType:NSDecimalAttributeType]; [request 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);
此致 哈拉尔德
答案 2 :(得分:0)
将您的给定源复制到新的iPhone项目并在模拟器中运行它在这里工作正常。我正在编译Snow Leopard上的3.1.2 SDK。
这是我用于数据模型的内容:
model description http://homepage.mac.com/aclark78/.Public/Pictures/test%20model.png
必须有其他事情导致您的问题。您能描述一下您的模型还是进一步简化它?