我已经看到人们在Core Data模型中使用整数类型的一些问题,但后来尝试在代码中使用整数而不设置复选框以使用标量。但是,我实际上是这样做的。
这会产生:
@interface State : NSManagedObject
@property (nonatomic) int64_t serverId;
@end
但是,然后,在运行时,我将使用以下代码获得EXC_BAD_ACCESS错误:
int64_t someValue = 313;
State *state = ... // standard [NSEntityDescription insert code
state.serverId = someValue;
其中'state'是NSManagedObject子类,serverId是Integer 64属性。 但是,以下代码有效:
state.serverId = [NSNumber numberFromInt:someValue];
但是,由于serverId实际上被声明为int64_t,因此会产生警告。并且,实际上尝试访问该值会产生可能是指针地址的内容(尽管%@看起来像我期望的那样)。
所以,我想我的问题是,Core Data中的哪些内容已经被我的int64_t作为NSNumber了?查看Model和NSAttributeDescription,它是一个NSInteger64AttributeType。
我认为可能与此有关的事情:
在第一个例子中,这似乎是一个常见的情况,我已经尝试过了,并且,正如预期的那样,我无法重现我的问题。对于第二种情况,我删除了我的模型文件并重新创建了所有内容,删除了我的DerivedData目录。
答案 0 :(得分:0)
如果您计划同时支持32位广告64位架构,则需要远离形式标量。
在您的代码中,请注意int
和NSInteger
在model
使用Integer32
或Integer64
。位大小取决于应用程序对数字空间的要求。如果你的服务器ID都在313左右,你应该可以使用32位,如果你有真正的大数字与integer64一起使用。
我知道你目前使用的是integer64。为了避免迁移的需要,现在只需坚持使用integer64。但是也要测试你的应用程序的32位架构。
在实体类中使用NSNumber,不要对存储中存储的属性使用标量。
@interface State : NSManagedObject
@property (nonatomic, retain) NSNumber *serverId;
@end
@implementation State
@dynamic serverId; // this will create the default accessor for you
@end
CoreData将完成从Integer32或Integer64转换为NSNumber的魔力,您无需担心转换警告。
在您的应用代码中使用numberFromInteger
而不是numberFromInt
state.serverId = [NSNumber numberFromInteger:someValue];
如果您有很多NSIntegers,并且想要编写类似
的内容 NSInteger someInteger;
state.serverIdInteger = someInteger;
// or
someInteger = state.serverIdInteger;
然后您将需要serverID
的自定义访问者。您的模型不会更改,更改是实体类。
@interface State : NSManagedObject
@property (nonatomic, retain) NSNumber *serverId;
@property (nonatomic) NSInteger serverIdInteger; //custom accessor
@end
@implementation State
@dynamic serverId; // this will create the default *serverId* accessor
// now do custom accessor
-(void)setServerIdInteger:(NSInteger)anInteger {
[self willChangeValueForKey:@"serverId"];
[self setServerId:[NSNumber numberWithInteger:anInteger]];
[self didChangeValueForKey:@"serverId"];
}
-(NSInteger)serverIdInteger {
[self willAccessValueForKey:@"serverId"];
NSNumber *tmpValue = [self serverId];
[self didAccessValueForKey:@"serverId"];
return (tmpValue!=nil) ? [tmpValue integerValue] : 0;
}
@end