如何将 C 原始类型放入 NSArray?

How to put a C primitive type in an NSArray?

我正在尝试创建一个 NSArray 来保存我将从磁盘加载的序列化文件的数据类型。
它可以说 doubleint 或一些自定义类型,然后我需要加载这些文件并将它们转换为 double/int/custom 类型。

有没有一种方法可以在 NSArray 中存储类型但不存储字符串?
到目前为止,似乎除了使用我在此示例中显示的字符串化类型之外别无他法。

有什么想法吗?

将原始值包装在 NSNumberNSValue 中。使用 NSNumber 表示简单的数值(布尔值、整数、浮点数、小数...)。将 NSValue 用于更抽象的结构(例如 NSRect)和任何可编码的 C 类型。这是一个例子:

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)]];

C 类型不是您可以存储的东西。没有像这样的 C 代码:

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

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

Objective-C 具有类型意识,但需要您将所有原始数据映射到 Objective-C class。例如

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]);
}

一般情况下,您不能存储没有值的类型;这是因为这样做真的没有任何价值。类型和值本质上是相关联的——在保持类型明确和保留一对一映射的同时切断它们表明存在严重的设计缺陷。