核心数据和 iPhone 的 NSDecimalNumber 问题

Posted

技术标签:

【中文标题】核心数据和 iPhone 的 NSDecimalNumber 问题【英文标题】:NSDecimalNumber question for core data and iPhone 【发布时间】:2011-03-06 20:09:37 【问题描述】:

我对核心数据和 iphone 编程相当陌生。也许这是一个显而易见的答案,所以如果有人能指出我的教程或其他资源,不胜感激! 我有一个核心数据实体,它是十进制类型,因为它处理货币,我读过的所有内容都说在处理货币时使用 NSDecimalNumber。话虽如此,我一生都无法弄清楚在插入新对象时如何设置值。这是我所拥有的

NSManagedObjectContext *moc = [self.fetchedResultsController managedObjectContext];
Envelope *envelope = [NSEntityDescription insertNewObjectForEntityForName:@"Envelope"
                                                inManagedObjectContext:moc];
[envelope setValue:@"Envelope 1" forKey:@"name"];
NSDecimalNumber *budgetNumber = [NSDecimalNumber decimalNumberWithDecimal:1.00];
[envelope setValue:budgetNumber forKey:@"budget"];

我在这里做错了什么? 提前致谢!

【问题讨论】:

你有什么问题?编译错误?碰撞?更多信息会有所帮助。 见***.com/questions/2035421/creating-nsdecimal 使用此代码,编译器告诉我它是“'decimalNumberWithDecimal:' 的参数 1 的不兼容类型:”有什么想法吗?再次感谢! 如果有人帮助您解决问题,请记住接受答案。 【参考方案1】:

试试这个:

NSDecimalNumber *budgetNumber = [NSDecimalNumber decimalNumberWithString:@"1.00"];

PS:为 cmets 中所述的第二个问题添加解决方案

(void)configureCell:(UITableViewCell *)cell withEnvelope:(NSManagedObject *)model 
     UILabel *envelopeNameLabel = (UILabel *) [cell viewWithTag:1];

     envelopeNameLabel.text = [model valueForKey:@"name"]; 

     UILabel *envelopeBudgetLabel = (UILabel *) [cell viewWithTag:2];
     envelopeBudgetLabel.text = [model valueForKey:@"budget"];
     

'NSInvalidArgumentException',原因: '-[NSDecimalNumber isEqualToString:]: 无法识别的选择器发送到实例 0x653fc80' .

此问题是由为字符串分配十进制数引起的。在将其分配给标签之前,您必须获取字符串表示形式。像这样的:

envelopeBudgetLabel.text = [[model valueForKey:@"budget"] description];

【讨论】:

谢谢@Manu。试过了,它编译得很好,但是应用程序崩溃了。日志显示:由于未捕获的异常 'NSInvalidArgumentException' 导致应用程序终止,原因:'-[NSDecimalNumber isEqualToString:]: unrecognized selector sent to instance 0x630db50' 我在完成输入之前按了回车键...关于它为什么不接受此代码的任何想法? 我已经测试了代码并且工作正常。该错误可能是由其他代码引起的?注释掉给定代码的最后两行并告诉我们结果。 嗯......好吧,@Manu,我相信你可能会有所收获。注释掉,日志显示同样的错误。当我尝试添加一个新对象时,它显示: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSDecimalNumber isEqualToString:]: unrecognized selector sent to instance 0x653fc80' 。谢谢。 我猜你正在尝试从核心数据中检索十进制数并直接将其与字符串进行比较,不是吗?贴出你使用 isEqualToString 的代码:比较或十进制数比较。【参考方案2】:

NSDecimalNumber 非常精确,应该精确构造:

NSDecimalNumber *budgetNumber = [NSDecimalNumber decimalNumberWithMantissa:1 exponent:0 isNegative:NO];

会给你一个 1 的 NSDecimalNumber 表示。如果你想要一个 -12.345 的 NSDecimalNumber 表示,那么它将被构造:

NSDecimalNumber *budgetNumber = [NSDecimalNumber decimalNumberWithMantissa:12345 exponent:-3 isNegative:YES];

【讨论】:

谢谢。前几天我刚拿起你关于 Core Data 的书。很有帮助! 感谢您的精彩解释。但即使我从字符串构造它,我也无法观察到任何精度损失。 (当然我不能检查小数点后 30 位)。真的有区别吗? 恕我直言,这是性能上的差异。解析字符串很昂贵。 另外,请注意NSDecimalNumber 提供了类方法one 来生成精确的数字1。

以上是关于核心数据和 iPhone 的 NSDecimalNumber 问题的主要内容,如果未能解决你的问题,请参考以下文章

iPhone 和 Apple Watch 应用之间的核心数据共享

iPhone - UITableViewController 和核心数据行在 tableView 中重复

iphone核心数据和实体继承

iphone, 以多对多关系保存数据, 核心数据

iPhone核心数据:如何在NIBS之间传递和获取实体

iPhone核心数据预设