Objective c XCode地板是否为“;“最小值”;及;“最大值”;对于核心数据十进制属性? 背景
一、 像我之前的许多程序员一样,我正在开发一个处理金钱的应用程序。我对Cocoa编程比较陌生,但在阅读了这些手册之后,我决定尝试使用Core Data,因为它提供了许多我想要的功能,应该可以避免我重新发明轮子。无论如何,我的问题与我是否应该使用核心数据无关:它与核心数据和XCode本身的行为有关 更新:我向苹果提交了一份缺陷报告,并被告知这是问题ID 9405079的副本。他们知道这个问题,但我不知道他们何时或是否会解决它 问题 由于某些我无法理解的原因,当我在托管对象模型中编辑十进制属性时,XCode会降低最小值和最大值约束。(我使用的是十进制属性。) 假设我有一个核心数据实体,它具有一个名为Objective c XCode地板是否为“;“最小值”;及;“最大值”;对于核心数据十进制属性? 背景,objective-c,xcode,cocoa,core-data,Objective C,Xcode,Cocoa,Core Data,一、 像我之前的许多程序员一样,我正在开发一个处理金钱的应用程序。我对Cocoa编程比较陌生,但在阅读了这些手册之后,我决定尝试使用Core Data,因为它提供了许多我想要的功能,应该可以避免我重新发明轮子。无论如何,我的问题与我是否应该使用核心数据无关:它与核心数据和XCode本身的行为有关 更新:我向苹果提交了一份缺陷报告,并被告知这是问题ID 9405079的副本。他们知道这个问题,但我不知道他们何时或是否会解决它 问题 由于某些我无法理解的原因,当我在托管对象模型中编辑十进制属性时,X
value
的十进制属性(这只是为了说明;我还使用了其他属性名称)。我希望它的值大于0,但因为XCode只允许我指定最小值(包括),所以我将Min value设置为0.01
。令我惊讶的是,这导致验证谓词SELF>=0
!当我更改最小值时,我得到了相同的结果:所有的分数值都被截断(最小值被截断)。最大值具有相同的行为
通过举例说明,以下屏幕截图中的
value
属性将导致验证谓词SELF>=0
和SELF=0.5
和SELF这是一个很长的截图,但您是否尝试过1,2而不是1.2?这很重要:
我想这是一个关于你问题的故事
记住小数点不是小数点,你会把小数点放在哪里
Floatingpoints的内部称为尾数…我做了另一个测试,我怀疑它与比较:
方法的NSNumber
和NSDecimalNumber
有关
NSDecimalNumber * dn = [NSDecimalNumber decimalNumberWithString:@"1.2"];
if ([dn compare:[NSNumber numberWithFloat:1.2]]==NSOrderedSame) {
NSLog(@"1.2==1.2");
}else{
NSLog(@"1.2!=1.2");
}
if ([[NSNumber numberWithFloat:1.2] compare:dn]==NSOrderedSame) {
NSLog(@"1.2==1.2");
}else{
NSLog(@"1.2!=1.2");
}
输出为:
2011-06-08 14:39:27.835 decimalTest[3335:903] 1.2==1.2
2011-06-08 14:39:27.836 decimalTest[3335:903] 1.2!=1.2
编辑:以下变通方法最初是我添加到问题中的一条评论,最终被改编成问题正文
使用-(BOOL)validate:(id*)ioValue error:(NSError**)outError
可以实现接近默认行为(as)的行为
例如(摘自问题正文,由OP Chris撰写):
-(BOOL)validateAmount:(id*)ioValue错误:(NSError**)outError{
//假设这是一个必需的属性。。。
如果(*ioValue==nil)
{
返回否;
}
if([*ioValue-floatValue]哦,这不是很尴尬吗……我只是试了一下,最大值的文本字段自动将我的输入更正为1。是的,我验证了行为,但我找不到任何东西表明它被错误地保存在.xcdatamodeld/entities文件中,所以我怀疑这不是真正的xcode。可能是运行时环境,也许你应该提交一份错误报告。你需要使用十进制类型有什么特殊原因吗?@Grady谢谢,我很高兴我不是唯一遇到这种情况的人。为了回答你的问题,我使用十进制数,因为它们提供了精确性(以10为基数的数学,而不是浮点精度),如前所述。我想您只需要实现自己的-(BOOL)validate:(id*)ioValue错误:(NSError**)outError,将最接近默认行为。@Grady谢谢你的建议!我刚刚更新了我的问题以包括你的解决方法。我实际上考虑过提交错误报告,但我不确定具体在哪里和/或如何提交。你能给我指出正确的方向吗?从(粗体格式是我的):"NSDecimalNumber
是NSNumber
的一个不可变子类,它为执行base-10算术提供了一个面向对象的包装器。一个实例可以表示任何可以表示为尾数x 10指数的数字,其中尾数是一个长达38位的十进制整数,指数是一个介于-128和-128之间的整数127"完全正确-没有分数-小数世界中有很多数字我不确定我是否理解你的意思。你能提供一些示例代码来说明你的答案吗?这似乎是逗号/点的问题。我最初认为它可能与浮点公差有关-我错过了它…这很有趣,我得到了相同的行为。你你会认为compare
是可交换的,但事实并非如此。我想知道在第一个条件语句中,NSNumber
是否被转换为NSDecimalNumber
,在第二个条件语句中,NSDecimalNumber
是否被转换为NSNumber
>-这比NSDecimalNumber
更容易出现浮点错误,因此无法通过平等性测试…是的,我不知道。这似乎是问题的根源,也许如果我们提交错误报告,我们会得到更好的答案1.2不应该有浮点问题,我想你无论如何都不能更新你的答案以包含你的建议关于使用-(BOOL)validate:(id*)ioValue error:(NSError**)outError
?这是我选择使用的解决方法,我想感谢您。如果/当我从苹果得到关于此错误的更新时,我会编辑我的问题以包括该信息。谢谢!我稍后会更新我的问题以消除冗余。
#import "DebugController.h"
@implementation DebugController
- (NSManagedObjectContext *)managedObjectContext
{
if (context == nil)
{
context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:[[appDelegate managedObjectContext] persistentStoreCoordinator]];
}
return context;
}
- (IBAction)updateLabel:sender
{
NSString *debugString = @"";
// TODO: Replace 'Wallet' with the name of your managed object model
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Wallet" inManagedObjectContext:[self managedObjectContext]];
NSArray *properties = [entity properties];
for (NSAttributeDescription *attribute in properties)
{
debugString = [debugString stringByAppendingFormat:@"\n%@: \n", [attribute name]];
NSArray *validationPredicates = [attribute validationPredicates];
for (NSPredicate *predicate in validationPredicates)
{
debugString = [debugString stringByAppendingFormat:@"%@\n", [predicate predicateFormat]];
}
}
// NSPredicate *validationPredicate = [validationPredicates objectAtIndex:1];
[debugLabel setStringValue:debugString];
}
@end
NSDecimalNumber * dn = [NSDecimalNumber decimalNumberWithString:@"1.2"];
if ([dn compare:[NSNumber numberWithFloat:1.2]]==NSOrderedSame) {
NSLog(@"1.2==1.2");
}else{
NSLog(@"1.2!=1.2");
}
if ([[NSNumber numberWithFloat:1.2] compare:dn]==NSOrderedSame) {
NSLog(@"1.2==1.2");
}else{
NSLog(@"1.2!=1.2");
}
2011-06-08 14:39:27.835 decimalTest[3335:903] 1.2==1.2
2011-06-08 14:39:27.836 decimalTest[3335:903] 1.2!=1.2
-(BOOL)validateAmount:(id *)ioValue error:(NSError **)outError {
// Assuming that this is a required property...
if (*ioValue == nil)
{
return NO;
}
if ([*ioValue floatValue] <= 0.0)
{
if (outError != NULL)
{
NSString *errorString = NSLocalizedStringFromTable(
@"Amount must greater than zero", @"Transaction",
@"validation: zero amount error");
NSDictionary *userInfoDict = [NSDictionary dictionaryWithObject:errorString
forKey:NSLocalizedDescriptionKey];
// Assume that we've already defined TRANSACTION_ERROR_DOMAIN and TRANSACTION_INVALID_AMOUNT_CODE
NSError *error = [[[NSError alloc] initWithDomain:TRANSACTION_ERROR_DOMAIN
code:TRANSACTION_INVALID_AMOUNT_CODE
userInfo:userInfoDict] autorelease];
*outError = error;
}
return NO;
}
return YES;
}