Search code examples
cocoacollectionsnsarraynsdictionarynsset

NSArray third party subclass to hold primitive value


Update: With new additions (subscripting and numerals), this question is out-of date.


I have seen recently some code for a class subclassing NSArray (or any collection class) to hold primitive values.

The idea was instead of writing:

myArray = [NSArray arrayWithObject:[NSNumber numberWithInt:42]];
[[myArray objectAtIndex:0] intValue];

you could write:

myArray = [NSPrimitiveObjectArray arrayWithObject:42];
[myArray objectAtIndex:0];

I can't find this code anymore. Would someone have seen it as well, and remember the url?

I would also appreciate feedback from people who have used it -or similar code- and what they think about it. The reason I didn't save the link when seeing this code was that I got a feeling of hacking with the language that might bring problems in the long term.


Solution

  • If I were doing this, I'd probably just write a category on NSArray and/or NSMutableArray. Something like this:

    @interface NSMutableArray (PrimitiveAccessors)
    
    - (void)addInteger:(NSInteger)value;
    - (NSInteger)integerAtIndex:(NSUInteger)index;
    - (void)addFloat:(float)value;
    - (float)floatAtIndex:(NSUInteger)index;
    
    // etc...
    
    @end
    
    @implementation NSMutableArray (PrimitiveAccessors)
    
    - (void)addInteger:(NSInteger)value;
    {
        [self addObject:[NSNumber numberWithInteger:value]];
    }
    
    - (NSInteger)integerAtIndex:(NSUInteger)index;
    {
        id obj = [self objectAtIndex:index];
        if (![obj respondsToSelector:@selector(integerValue)]) return 0;
        return [obj integerValue];
    }
    
    - (void)addFloat:(float)value;
    {
        [self addObject:[NSNumber numberWithFloat:value]];
    }
    
    - (float)floatAtIndex:(NSUInteger)index;
    {
        id obj = [self objectAtIndex:index];
        if (![obj respondsToSelector:@selector(floatValue)]) return 0;
        return [obj floatValue];
    }
    
    // etc...
    
    @end
    

    Really though, it sort of seems like more work than it's worth. Wrapping primitives in NSNumber and pulling them back out just isn't that hard...