Re: Core Data and NSNumber values
Re: Core Data and NSNumber values
- Subject: Re: Core Data and NSNumber values
- From: Quincey Morris <email@hidden>
- Date: Thu, 6 Nov 2008 23:48:14 -0800
On Nov 6, 2008, at 21:23, HAMILTON, Steven wrote:
I think I'm missing something with Core Data. Value attributes
always appear to be stored as an NSNumber with the exception of
Decimal types which are stored as NSDecimalNumber. If I choose an
attribute to be INT64 then this type doesn't seem to be enforced. I
can store any valid NSNumber object in that attribute. There's two
issues with understanding;
1) I just want to store INT scalar values. I don't want an
Object class stored at all. I want an INT back, not an NSNumber.
2) I want the type enforced so I can't store a decimal when I
want an INT.
The docs make no mention of NSNumber's being returned. They all
mention normal scalar values.
Core Data is an object-graph system. Its attributes are objects. You
can't stop it from storing numbers as objects, and you can't make it
store anything as a non-object. (It wouldn't save you much because you
don't want to store scalar memory-bit-images -- they're not portable
between architectures. NSNumbers take care of bit/byte ordering and
floating point representation issues for you for free.) So now you
have 2 issues:
1. What if I want scalar accessors?
You write your own. The documentation is a bit obscure, because it
mostly talks about more complicated accessor scenarios:
http://developer.apple.com/documentation/Cocoa/Conceptual/CoreData/Articles/cdAccessorMethods.html#/
/apple_ref/doc/uid/TP40002154-SW14
http://developer.apple.com/documentation/Cocoa/Conceptual/CoreData/Articles/cdNSAttributes.html#/
/apple_ref/doc/uid/TP40001919
but it's fairly straightforward for numeric types. You specify that
your data model entity has a custom class, then write it along these
lines:
@interface MyManagedObject : NSManagedObject
...
@property NSInteger myInteger;
...
@end
@interface MyManagedObject (CoreDataGeneratedPrimitiveAccessors) //
to keep the compiler from complaining ...
- (NSNumber*) primitiveMyInteger;
- (void) setPrimitiveMyInteger: (NSNumber*) value;
@end
@implementation MyManagedObject
...
- (NSInteger) myInteger {
[self willAccessValueForKey: @"myInteger"];
NSNumber *value = self.primitiveMyInteger;
[self didAccessValueForKey: @"myInteger"];
return [value integerValue];
}
- (void) setMyInteger: (NSInteger) newValue {
[self willChangeValueForKey: @"myInteger"];
self.primitiveMyInteger = [NSNumber numberWithInteger: newValue];
[self didChangeValueForKey: @"myInteger"];
}
...
- (void) setNilValueForKey: (NSString*) key {
if ([key isEqualToString: @"myInteger"])
self.myInteger = 0; // or however else you want to handle this
else
[super setNilValueForKey: key];
}
...
@end
You can actually get most of this by using Xcode's Design | Data Model
| Copy Obj-C 2.0 Method Implementations to Clipboard function, and
then massage the code it gives you.
Because you have to go to some trouble to provide scalar accessors,
it's worth asking whether you want them enough to write the code for
them.
2. What if I want the number range to be limited to a certain number
of bits (like 32)?
I would assume, though I haven't tested it, that if you try to save a
NSNumber that lies outside the range of its Core Data entity type,
you'll get a validation error at save time. You can prevent this by
properly validating your numeric attributes. It's not precisely an
issue with NSNumbers, but something you need to deal with generally.
If you're worried about setting a NSNumber with a non-integral value
to an attribute of integral type, it's much the same as assigning a
float to an int -- there's no compiler warning, and the fractional
part disappears. Well, with NSNumbers, the fractional part doesn't
actually disappear, but may be harmless. If it matters, you can apply
validation to that, too. You might get a validation error at save
time, I don't know.
Of course, if you write your own scalar accessors, there is no
NSNumber range issue.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden