sramij
sramij

Reputation: 4925

How to put a C primitive type in an NSArray?

I am trying create an NSArray which holds the datatype of serialized files i will be loading from disk.
It can say double, int, or some custom type, and then I will need to load those files and cast them to double/int/custom type.

Is there a way I can store types in NSArray but not store strings?
so far, it seems that there is no way but to use stringified types as I show in this example.

any ideas?

Upvotes: -2

Views: 641

Answers (2)

Tommy
Tommy

Reputation: 100652

C types are not something you can store. There's no C code like:

type types[10];
types[0] = typeof(int);

*target = *(types[0] *)&source;

Objective-C has type awareness, but would require you to map all of your original data to an Objective-C class. E.g.

NSArray *objects = [[NSArray alloc] init]; // Old-school non-lightweight-templated, to hold anything

[objects addObject:[NSNumber numberWithInt:23]];
[objects addObject:[NSNumber numberWithFloat:23.0f]];
[objects addObject:@"I'm a string"];

...

if([objects[0] isKindOfClass:[NSString class]]) {
    NSLog(@"Object zero is the string %@", objects[0]);
}
if([objects[0] isKindOfClass:[NSNumber class]]) {
    CFNumberType numberType = CFNumberGetType(number);
    ... table here to map the enum numberType to a string ...
    NSLog(@"Object zero is a number of type %@ with value %@", type, objects[0]);
}

You can't in general store types without values; this is because there's really no value whatsoever in doing so. Type and value are inherently connected — severing them while keeping type explicit and retaining a one-to-one mapping suggests a severe design deficiency.

Upvotes: 2

James Bucanek
James Bucanek

Reputation: 3439

Wrap the primitive value in an NSNumber or NSValue. Use NSNumber for simple numeric values (Boolean, integer, floating point, decimal, ...). Use NSValue for more abstract structures (NSRect, for example) and any encodable C type. Here's an example:

NSUInteger a = 1234;
double b = 12.34;
NSRect c = NSMakeRect(0.0,100.0,200.0,300.0);
SomeWeirdCType d = ?
NSMutableArray<NSValue*>* valueList = [NSMutableArray array];
[valueList addObject:[NSNumber numberWithUnsignedInteger:a]]; // legacy
[valueList addObject:@(b); // modern ObjC compiler syntax, auto-boxes as NSNumber
[valueList addObject:[NSValue valueWithRect:c]];
[valueList addObject:[NSValue value:&d withObjCType:@encode(SomeWeirdCType)]];

Upvotes: 2

Related Questions