鉴于我有一个由method_copyReturnType()返回的类型说明符。在随GCC提供的GNU运行时中,有多种方法可以使用类似objc_sizeof_type()
,objc_alignof_type()
等类型说明符。
使用Apple运行时时,没有这样的方法。
如何使用Apple运行时解释类型说明符字符串(例如获取类型的大小)而不为自己实现if / else或case开关?
[更新]
我无法使用Apple Foundation。
答案 0 :(得分:5)
我相信你正在寻找NSGetSizeAndAlignment
:
获得编码类型的实际大小和对齐大小。
const char * NSGetSizeAndAlignment ( const char *typePtr, NSUInteger *sizep, NSUInteger *alignp );
<强>讨论强>
获得typePtr
表示的第一个数据类型的实际大小和对齐大小,并返回指向typePtr
中下一个数据类型位置的指针。
这是一个基础功能,不是基本运行时的一部分,这可能是你找不到它的原因。
更新: 虽然您最初没有提到您正在使用Cocotron,但它也可以在那里使用。您可以在NSObjCRuntime.m中的Cocotron基金会找到它。
显然,这比滚动自己要好得多,因为您可以信任它始终正确处理由自己的运行时生成的字符串,万一编码字符应该更改。
然而,出于某种原因,它无法处理方法签名字符串的数字元素(可能与内存中的偏移量有关)。 This improved version, by Mike Ash会这样做:
static const char *SizeAndAlignment(const char *str, NSUInteger *sizep, NSUInteger *alignp, int *len)
{
const char *out = NSGetSizeAndAlignment(str, sizep, alignp);
if(len)
*len = out - str;
while(isdigit(*out))
out++;
return out;
}
答案 1 :(得分:2)
afaik,你需要将这些信息烘焙到你的二进制文件中。只需创建一个函数,该函数在结构中返回sizeof和alignof,支持您必须支持的类型,然后为该信息调用该函数(或类方法)。
下面的程序向您展示了许多基元只是一个字符。因此,该函数的大部分实现可能是一个开关。
static void test(SEL sel) {
Method method = class_getInstanceMethod([NSString class], sel);
const char* const type = method_copyReturnType(method);
printf("%s : %s\n", NSStringFromSelector(sel).UTF8String, type);
free((void*)type);
}
int main(int argc, char *argv[]) {
@autoreleasepool {
test(@selector(init));
test(@selector(superclass));
test(@selector(isEqual:));
test(@selector(length));
return 0;
}
}
然后您可以将此作为起点:
typedef struct t_pair_alignof_sizeof {
size_t align;
size_t size;
} t_pair_alignof_sizeof;
static t_pair_alignof_sizeof MakeAlignOfSizeOf(size_t align, size_t size) {
t_pair_alignof_sizeof ret = {align, size};
return ret;
}
static t_pair_alignof_sizeof test2(SEL sel) {
Method method = class_getInstanceMethod([NSString class], sel);
const char* const type = method_copyReturnType(method);
const size_t length = strlen(type);
if (1U == length) {
switch (type[0]) {
case '@' :
return MakeAlignOfSizeOf(__alignof__(id), sizeof(id));
case '#' :
return MakeAlignOfSizeOf(__alignof__(Class), sizeof(Class));
case 'c' :
return MakeAlignOfSizeOf(__alignof__(signed char), sizeof(signed char));
...