如何在NSArray中放置C基元类型?

时间:2018-01-31 16:54:28

标签: objective-c objective-c-2.0

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

有没有办法可以在NSArray中存储类型而不存储字符串?
到目前为止,似乎没有办法,只能使用字符串化类型,如我在本例中所示。

任何想法?

2 个答案:

答案 0 :(得分:2)

将原始值包含在NSValueNSNumber中。使用NSRect表示简单数值(布尔值,整数,浮点数,小数......)。使用NSValue获取更多抽象结构(例如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类型。这是一个例子:

############################ Fail to Pass Compilation(Case I)
# hello.pxd
cdef extern from "time.h":
    cdef struct timespec:
        uint64_t tv_sec
        uint64_t tv_nsec

# world.pyx
cimport hello

cdef class Info:
    cdef public hello.timespec ts

########################### Fail to Pass Compilation(Case II)
# hello.pxd
cdef extern from "time.h":
    cdef struct timespec:
        uint64_t tv_sec
        uint64_t tv_nsec

# world.pyx
cimport hello
from hello cimport timespec as hello_timespec
cdef class Info:
    cdef public hello_timespec ts    

########################################
Error compiling Cython file:
------------------------------------------------------------
...
    PyTypeObject *Py_TYPE(obj)
    bint PyMapping_Check(obj)
    object PyErr_Format(exc, const char *format, ...)

@cname("__pyx_convert__from_py_struct__timespec")
cdef timespec __pyx_convert__from_py_struct__timespec(obj) except *:
    ^
------------------------------------------------------------

FromPyStructUtility:11:5: 'timespec' is not a type identifier

Error compiling Cython file:
------------------------------------------------------------
...
    bint PyMapping_Check(obj)
    object PyErr_Format(exc, const char *format, ...)

@cname("__pyx_convert__from_py_struct__timespec")
cdef timespec __pyx_convert__from_py_struct__timespec(obj) except *:
    cdef timespec result
        ^
------------------------------------------------------------

FromPyStructUtility:12:9: 'timespec' is not a type identifier


################################### Pass Compilation(Case III)
# hello.pxd
cdef extern from "time.h":
    cdef struct timespec:
        uint64_t tv_sec
        uint64_t tv_nsec

# world.pyx
cimport hello
from hello cimport timespec

cdef class Info:
    cdef public timespec ts

答案 1 :(得分:2)

C类型不是你可以存储的东西。没有C代码,如:

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

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

Objective-C具有类型感知功能,但需要您将所有原始数据映射到Objective-C类。 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]);
}

一般商店类型没有价值;这是因为这样做真的没有任何价值。类型和值本质上是相互关联的 - 在保持类型显式的同时切断它们并保留一对一的映射表明存在严重的设计缺陷。