I want to add a property to an NSNumber class, so I have to subclass it. The documentation states that I then have to override all NSValue primitive methods. Since the NSValue documentation does not state which methods are the primitive ones, I figured that these two are probably the primitive ones for instantiation:
– initWithBytes:objCType:
+ valueWithBytes:objCType:
So I made my class as:
@interface MultipleNumber : NSNumber {
NSNumber *_number;
}
@property (nonatomic, getter = isMultiple) BOOL multiple;
@end
@implementation MultipleNumber
@synthesize multiple=_multiple;
-(id)initWithBytes:(const void *)value objCType:(const char *)type {
self = [super init];
if (self) {
_number=[[NSNumber alloc] initWithBytes:value objCType:type];
}
return self;
}
+(NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type {
return [[[MultipleNumber alloc] initWithBytes:value objCType:type] autorelease];
}
-(void)getValue:(void *)value { [_number getValue:value]; }
-(const char *)objCType { return [_number objCType]; }
@end
But when I call[NSNumber numberWithBool:YES], I still get a _NSCFBoolean class back and the "primitive methods" are not called. How can I figure out what methods are considered primitive?
You don't need to subclass NSNumber
in order to add a property. You can add a property more easily using an associative reference. Subclassing NSNumber
is quite tricky because it's a class cluster.
EDIT: @Remco makes an important point down in his comments to @diablosnuevos that I wanted to call out in an answer:
Yes, I finally did make a subclass by trial and error, because the NSNumbers returned are shared instances, so storing a associated reference is also shared. – Remco Poelstra May 16 at 9:09
This is a really important thing to remember. NSNumber
caches the integers from -1 to 12 and treats them as singletons. In OSX 10.7, NSNumber
is implemented as a tagged pointer (haven't dug into the implications for associated references there). The point is that while associated references are quite useful, there can be underlying implementation details that will burn you.
The deeper lesson here is that subclassing or augmenting NSNumber
probably isn't a good idea in any case. NSNumber
is a very low-level object. It's almost certainly better to build another class that owns an NSNumber
, much like NSAttributedString
owns an NSString
rather than extending NSString
.
I don't know the specifics of the problem being solved here, but the problems encountered make for an interesting lesson.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With