我正在将现有的iOS应用移植到Core Data(Xcode 5,Mavericks,iOS 7.1+)。我需要导入一个现有的sqlite3数据库。我自动生成模型文件,然后用数据库中的数据填充它们。
我有一个包含标量类型的自动生成的类(我在自动生成时选中了Use Scalars框):
@interface Details : NSManagedObject
@property (nonatomic) float heightInches;
…
自动生成实现此属性:
@implementation Details
@dynamic heightInches;
…
然后我尝试使用数据库中的float设置此属性的值:
Details* details = [NSEntityDescription insertNewObjectForEntityForName:@“Details” inManagedObjectContext:context];
[details setHeightInches:(float)sqlite3_column_double(statement, 10)];
…
当这一行执行时,我得到以下运行时错误:
' NSInvalidArgumentException',原因:'不可接受的值类型 attribute:property =" heightInches&#34 ;;所需类型= NSNumber;特定 type = NSManagedObject;值= (entity:Details; id:0x1002286a0 ;数据: { heightInches = 0; ...
如果重新定义实现,我会得到相同的运行时错误:
@synthesize heightInches;
如果我尝试传入NSNumber而不是浮点数,则会出现编译时错误(类型不匹配):
[details setHeightInches:[NSNumber numberWithFloat:(float)sqlite3_column_double(statement, 10)]];
为什么Core Data在数据类型为float时期望NSNumber?为什么Core Data会看到我作为NSManagedObject传入的浮点数? int32_t值似乎正在工作。我有什么特别需要的花车吗?
由于
答案 0 :(得分:1)
我会采取一种有点逆向的方法,并认为它并不重要因为你做出了糟糕的设计决定,甚至试图以这种方式做事。
您在评论中提到这是科学数据。但是你要将它分配给float
,由于在浮点变量中表示十进制值的常见问题,这会导致精度不足。
您应该做的是将数据模型中的属性声明为Decimal
。当您生成将表示为NSDecimalNumber
的子类时(没有标量等效项,因此选中该框不会产生任何差异)。 NSDecimalNumber
当然不是完美的,但如果你有十进制值并且非常关心精确度(例如:科学,金融),那么它是正确的选择。
至于在这种情况下究竟出了什么问题,我并不完全确定。使用setHeightInches
应该完全按照您希望的方式工作。您的错误消息表明,除了您的问题中的详细信息之外,还有更多内容,因为它没有抱怨想要NSNumber
而不是float
。它抱怨它收到了NSManagedObject
作为值,但代码段没有显示出来。但这并不重要,因为float
在这种情况下仍然是错误的选择。