objective-c – 核心数据十进制属性的XCode楼层“最小值”和“最大值”?

objective-c – 核心数据十进制属性的XCode楼层“最小值”和“最大值”?,第1张

概述背景 我,像我之前的几十个程序员,我正在处理一个应用程序的钱。我对Cocoa编程相对陌生,但是在阅读了手册之后,我决定使用Core Data,因为它提供了许多我想要的功能,并且应该可以避免重新发明轮子。无论如何,我的问题与我是否应该使用Core Data没有任何关系:它与Core Data和XCode自身的行为有关。 更新:我提交了一个错误报告与苹果和被通知,这是一个重复的问题ID 9405079 背景

我,像我之前的几十个程序员,我正在处理一个应用程序的钱。我对Cocoa编程相对陌生,但是在阅读了手册之后,我决定使用Core Data,因为它提供了许多我想要的功能,并且应该可以避免重新发明轮子。无论如何,我的问题与我是否应该使用Core Data没有任何关系:它与Core Data和XCode自身的行为有关。

更新:我提交了一个错误报告与苹果和被通知,这是一个重复的问题ID 9405079.他们知道这个问题,但我不知道什么时候或者如果他们要解决它。

问题

由于某些原因我不能理解,当我在我的托管对象模型中编辑一个十进制属性时,XCode限制了最小值和最大值约束。 (我使用十进制属性为the reasons described here.)

假设我有一个具有名为值的十进制属性的核心数据实体(这只是为了说明;我也使用了其他属性名称)。我希望它的值大于0,但因为XCode将只允许我指定一个最小值(包括),我设置最小值等于0.01。令我感到惊讶的是,这导致SELF> = 0的验证谓词!当我改变最小值时,我得到相同的结果:所有小数值都被截断(最小值被忽略)。最大值具有相同的行为。

作为说明,以下屏幕截图中的值属性将导致SELF> = 0和SELF< = 1的验证谓词。 奇怪的是,如果我将此属性的类型更改为Double或float,验证谓词将按预期更改为SELF> = 0.5和SELF< = 1.2。陌生人仍然,如果我创建我自己的数据模型在Core Data Utility Tutorial之后,验证谓词被正确设置,即使对于十进制属性。

原始解决方法

因为我找不到任何办法来解决这个问题在XCode的管理对象模型编辑器中,我已经添加了以下代码(由开始解决方法和结束解决方法注释指示)到我的应用程序委托的managedobjectModel方法(这是相同的应用程序委托默认情况下,XCode在创建使用Core Data的新项目时提供)。注意,我添加一个约束来保持事务实体的amount属性大于0。

- (NSManagedobjectModel *)managedobjectModel {    if (managedobjectModel) return managedobjectModel;    managedobjectModel = [[NSManagedobjectModel mergedModelFromBundles:nil] retain];    // begin workaround    NSEntityDescription *transactionEntity = [[managedobjectModel entitIEsByname] objectForKey:@"Transaction"];    NSAttributeDescription *amountAttribute = [[transactionEntity attributesByname] objectForKey:@"amount"];    [amountAttribute setValIDationPredicates:[NSArray arrayWithObject:[nspredicate predicateWithFormat:@"SELF > 0"]]                      withValIDationWarnings:[NSArray arrayWithObject:@"amount is not greater than 0"]];    // end workaround    return managedobjectModel;}

问题

>这是否真的是XCode如何为Core Data的管理对象模型中的十进制属性生成验证谓词的错误?
>如果是这样,有没有一个更好的方式来解决它比我在这里描述的?

Repro代码

您应该能够使用DeBUGController类的以下示例代码重现此问题,该类会将托管对象模型中的每个属性的约束打印到标签。此代码做出以下假设。

>您有一个名为DecimalTest_AppDelegate的应用程序委托
>您的应用程序委托具有managedobjectContext方法
>您的托管对象模型命名为“Wallet”

执行以下步骤使用此代码。

>在Interface Builder中实例化DeBUGController。
>将控制器的appDelegate插座连接到应用程序代理。
>在用户界面中添加一个包装标签(NSTextFIEld),并将控制器的deBUGLabel插座连接到它。
>向用户界面添加按钮,并将其选择器连接到控制器的updateLabel *** 作。
>启动应用程序并按下与updateLabel *** 作相连的按钮。这将打印您的托管对象模型的约束到deBUGLabel,并应该说明我在这里描述的行为。

DeBUGController.h

#import <Cocoa/Cocoa.h>// Todo: Replace 'DecimalTest_AppDelegate' with the name of your application delegate#import "DecimalTest_AppDelegate.h"@interface DeBUGController : NSObject {    NSManagedobjectContext *context;    // Todo: Replace 'DecimalTest_AppDelegate' with the name of your application delegate    IBOutlet DecimalTest_AppDelegate *appDelegate;    IBOutlet NSTextFIEld *deBUGLabel;}@property (nonatomic,retain,Readonly) NSManagedobjectContext *managedobjectContext;- (IBAction)updateLabel:sender;@end

DeBUGController.m

#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

感谢大家。

解决方法 我做了另一个测试,我怀疑它与NSNumber和NSDecimalNumber的compare:方法。

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.22011-06-08 14:39:27.836 decimalTest[3335:903] 1.2!=1.2

编辑:以下解决方法最初是一个评论,我添加到问题,最终调整到问题正文。

使用 – (BOol)valIDate< key> 总结

以上是内存溢出为你收集整理的objective-c – 核心数据十进制属性的XCode楼层“最小值”和“最大值”?全部内容,希望文章能够帮你解决objective-c – 核心数据十进制属性的XCode楼层“最小值”和“最大值”?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1042692.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存