2009-11-08 24 views
3

我第一次發佈到這一輪,所以如果我沒有正確遵守所有規則,請耐心等待。通過核心數據計算小數值的總和不正常?

我正在爲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計數]:無法識別的選擇發送到實例。 「

不過,只是在沒有聚合函數的情況下評估keyPathExpression效果不錯。

reference documentation顯示完全相同的例子,所以我想知道我做錯了什麼。或者這可能只是一個錯誤?

一切順利, 哈拉爾

+2

我也遇到過這個;認爲這是Core Data中的一個錯誤,因爲它在SQL存儲中工作,但不在內存中。當我有機會的時候我會用雷達記錄這些信息。 – 2010-03-17 13:35:35

回答

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]); 
+0

當指定一個'NSDictionaryResultType'時,您將通過'executeFetchRequest:error:'收到一個包含一個對象的數組。 – 2010-01-14 03:19:37

+0

這就是我從內存中獲得靈感的原因。 – TechZen 2010-01-14 14:03:35

0

謝謝你讓我知道。問題是我實際上不想使用託管對象。畢竟,我只對數量感興趣,而這正是我用字典得到的。

此外,試圖調查問題,因爲你描述沒有工作,因爲執行抓取請求立即失敗,我什麼都沒有回來。

還有其他想法嗎?有沒有其他的可能性來獲得聚合值?任何「最佳實踐」?目前我執行以下操作(繼續上面的代碼):

NSExpressionDescription * expressionDescription = [[NSExpressionDescription alloc] init]; [expressionDescription setName:@「amount」]; [expressionDescription setExpression:keyPathExpression]; [expressionDescription 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); 

問候, 哈拉爾

+0

嘿Harald,請不要張貼您的回答作爲您的問題的答案。相反,您應該使用「添加評論」功能直接回復答案/評論,並在找到附加信息時編輯您的問題。 – 2010-01-14 03:29:19

+0

你需要一定數量的聲望來評論,更新原來的問題是好的,雖然...只是添加一個新的部分與更新的信息,所以你仍然可以看到原始問題 – monowerker 2010-01-14 03:45:40

0

複製你的給定源到一個新的iPhone項目,並運行在模擬器的工作在這裏很好。我正在針對Snow Leopard上的3.1.2 SDK進行編譯。

這是我使用的數據模型:

model description http://homepage.mac.com/aclark78/.Public/Pictures/test%20model.png

一定有別的事情上造成您的問題。你能描述一下你的模型還是進一步簡化它?

+0

請參閱我對原始問題的評論;我是你使用SQL存儲? – 2010-03-17 13:36:28