Til*_*ütz 6 objective-c objective-c-runtime
鉴于我有一个由method_copyReturnType()返回的类型说明符.在随GCC提供的GNU运行时中,有各种方法可以使用类似的类型说明符objc_sizeof_type(),objc_alignof_type()以及其他类型.
使用Apple运行时时,没有这样的方法.
如何使用Apple运行时解释类型说明符字符串(例如获取类型的大小)而不为自己实现if/else或case开关?
[更新]
我无法使用Apple Foundation.
我相信你正在寻找NSGetSizeAndAlignment:
获得编码类型的实际大小和对齐大小.
Run Code Online (Sandbox Code Playgroud)const char * NSGetSizeAndAlignment ( const char *typePtr, NSUInteger *sizep, NSUInteger *alignp );讨论
获得由第一个数据类型表示的实际大小和对齐大小,typePtr并返回指向下一个数据类型位置的指针typePtr.
这是一个Foundation函数,不是基本运行时的一部分,这可能是您找不到它的原因.
更新:虽然你最初没有提到你正在使用Cocotron,但它也可以在那里使用.你可以找到它在Cocotron的基础上,在 NSObjCRuntime.m.
显然,这比滚动自己要好得多,因为您可以信任它始终正确处理由自己的运行时生成的字符串,万一编码字符应该更改.
但是,出于某种原因,它无法处理方法签名字符串的数字元素(可能与内存中的偏移量有关).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;
}
Run Code Online (Sandbox Code Playgroud)
据我所知,您需要将该信息烘焙到您的二进制文件中。只需创建一个函数,该函数返回结构中的 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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以使用它作为起点:
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));
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1358 次 |
| 最近记录: |