Objective c XCode地板是否为“;“最小值”;及;“最大值”;对于核心数据十进制属性? 背景

Objective c XCode地板是否为“;“最小值”;及;“最大值”;对于核心数据十进制属性? 背景,objective-c,xcode,cocoa,core-data,Objective C,Xcode,Cocoa,Core Data,一、 像我之前的许多程序员一样,我正在开发一个处理金钱的应用程序。我对Cocoa编程比较陌生,但在阅读了这些手册之后,我决定尝试使用Core Data,因为它提供了许多我想要的功能,应该可以避免我重新发明轮子。无论如何,我的问题与我是否应该使用核心数据无关:它与核心数据和XCode本身的行为有关 更新:我向苹果提交了一份缺陷报告,并被告知这是问题ID 9405079的副本。他们知道这个问题,但我不知道他们何时或是否会解决它 问题 由于某些我无法理解的原因,当我在托管对象模型中编辑十进制属性时,X

一、 像我之前的许多程序员一样,我正在开发一个处理金钱的应用程序。我对Cocoa编程比较陌生,但在阅读了这些手册之后,我决定尝试使用Core Data,因为它提供了许多我想要的功能,应该可以避免我重新发明轮子。无论如何,我的问题与我是否应该使用核心数据无关:它与核心数据和XCode本身的行为有关

更新:我向苹果提交了一份缺陷报告,并被告知这是问题ID 9405079的副本。他们知道这个问题,但我不知道他们何时或是否会解决它

问题 由于某些我无法理解的原因,当我在托管对象模型中编辑十进制属性时,XCode会降低最小值最大值约束。(我使用的是十进制属性。)

假设我有一个核心数据实体,它具有一个名为
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;
}