NSNumber documentation/header does not specify which methods are the primitive ones
| Originator: | aufflick | ||
| Number: | rdar://15205057 | Date Originated: | 2013-10-11 |
| Status: | Open | Resolved: | |
| Product: | OSX & iOS SDKs | Product Version: | |
| Classification: | Reproducible: | Always |
Summary:
NSNumber is a class cluster, consequently to create a subclass a developer needs to create their own storage and implement the primitive methods. Indeed the NSNumber docs specify that it is the primitive methods of NSValue that need to be implemented.
> As with any class cluster, if you create a subclass of NSNumber, you have to override the primitive methods of its superclass, NSValue.
Firstly, the NSValue documentation makes no mention of what are its primitive methods. Based on NSValue.h I assumed getValue: and objcCType are.
The next problem is that implementing these is not sufficient to create a functioning subclass of NSNumber (ie. one that doesn't beach-ball the app). A functioning subclass that only ever deals with int values requires intValue, but that will fail (hang) for eg. double values, which require doubleValue.
So the documentation is incorrect (methods off NSNumber as well as NSValue are required) as well as incomplete.
I'm also wondering why methods like intValue aren't implemented in terms of getValue: and objCType. I understand there are performance considerations but would have thought that any special fast paths would be avoided for non-Apple subclasses.
Consequently I'm not sure whether this is a documentation or functionality bug - your call I guess :)
Steps to Reproduce:
1. Subclass NSNumber
2. Realise that the docs don't fully specify which NSValue primitive methods need implementing
3. Assuming the worst, implement *all* NSValue methods
Expected Results:
A functioning NSNumber class cluster subclass.
Actual Results:
A class which hangs your app when attempting to call eg. description or hangs Xcode when inspecting an instance in the debugger.
Version:
Xcode 5.0 (5A1413)
Notes:
If I implement all of the below, my class seems to function correctly, although the description and comparison methods seem unnecessary:
- (void)getValue:(void *)value { return [_number getValue:value]; }
- (const char *)objCType { return [_number objCType]; }
- (char)charValue { return [_number charValue]; }
- (unsigned char)unsignedCharValue { return [_number unsignedCharValue]; }
- (short)shortValue { return [_number shortValue]; }
- (unsigned short)unsignedShortValue { return [_number unsignedShortValue]; }
- (int)intValue { return [_number intValue]; }
- (void *)pointerValue { return [_number pointerValue]; }
- (unsigned int)unsignedIntValue { return [_number unsignedIntValue]; }
- (long)longValue { return [_number longValue]; }
- (unsigned long)unsignedLongValue { return [_number unsignedLongValue]; }
- (long long)longLongValue { return [_number longLongValue]; }
- (unsigned long long)unsignedLongLongValue { return [_number unsignedLongLongValue]; }
- (float)floatValue { return
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!