iOS的iOS NSMethodSignature(或编码) [英] iOS NSMethodSignature (or encoding) of NSBlock

查看:80
本文介绍了iOS的iOS NSMethodSignature(或编码)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一种在运行时检查给定块的参数和参数类型的数量的方法(我正在编写的某些对象映射库需要此方法,我正在将字符串格式的值映射到选择器,想要相同(用于块).

I need a way to check the number of arguments and argument types of a given block at runtime (I need this for some object mapping library I'm currently writing, I'm mapping String formatted values to selectors, want the same for blocks).

我尝试了以下示例中的代码,但是由于某种原因,它对我不起作用,并且返回nil作为字符串描述.

I tried code from below examples, but for some reason it's not working for me and returnin nil for the string description.

您是否知道一种在运行时评估块签名的方法(对于iPhone应用商店提交,最好是afe)?

Do you know a way to evaluate block signatures at runtime(preferably afe for iPhone app store submissions)?

这是我使用的代码:

struct BlockDescriptor {
unsigned long reserved;
unsigned long size;
void *rest[1];
};

struct Block {
void *isa;
int flags;
int reserved;
void (*invoke)(struct __block_literal_1 *);
struct BlockDescriptor *descriptor;
};

enum {
BLOCK_HAS_COPY_DISPOSE = (1 << 25),
BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code
BLOCK_IS_GLOBAL = (1 << 28),
BLOCK_HAS_STRET = (1 << 29), // IFF BLOCK_HAS_SIGNATURE
BLOCK_HAS_SIGNATURE = (1 << 30),
};

static const char *BlockSig(id blockObj)
{
struct Block *block = (void *)blockObj;
struct BlockDescriptor *descriptor = block->descriptor;

assert(block->flags & BLOCK_HAS_SIGNATURE);

int index = 0;
if(block->flags & BLOCK_HAS_COPY_DISPOSE)
    index += 2;

return descriptor->rest[index];
}


-(NSString*)signatureForBlock:(id)block {
NSString* sig = [NSString stringWithUTF8String:BlockSig(block)];

sig = [sig substringFromIndex:1]; // remove c
NSArray* components = [sig componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"0123456789?"]];
sig = [components componentsJoinedByString:@""];

return sig;
}

然后做:

NSString * (^block)(int, NSArray *) = ^NSString * (int i, NSArray * a){
    return @"Oh, yeah!";
};
NSLog(@"signature %s", BlockSig(block)); // ==> this returns null

来源: 检查Objective-C块类型? https://github.com/mikeash/MABlockForwarding/blob/master/main. m

推荐答案

使用 CTBlockDescription ,您可以作为

Using CTBlockDescription, you can get all the runtime information you need as a NSMethodSignature object. Usage is straightforward:

NSString * (^block)(int, NSArray *) = ^NSString * (int i, NSArray * a){
    return @"Oh, yeah!";
};
NSMethodSignature *signature = [[[CTBlockDescription alloc] initWithBlock:block] blockSignature];
NSLog(@"signature %@", [signature debugDescription]);

这将输出以下签名:

signature <NSMethodSignature: 0x6844900>
    number of arguments = 3
    frame size = 12
    is special struct return? NO
    return value: -------- -------- -------- --------
        type encoding (@) '@'
        flags {isObject}
        modifiers {}
        frame {offset = 0, offset adjust = 0, size = 4, size adjust = 0}
        memory {offset = 0, size = 4}
    argument 0: -------- -------- -------- --------
        type encoding (@) '@?'
        flags {isObject}
        modifiers {}
        frame {offset = 0, offset adjust = 0, size = 4, size adjust = 0}
        memory {offset = 0, size = 4}
    argument 1: -------- -------- -------- --------
        type encoding (i) 'i'
        flags {isSigned}
        modifiers {}
        frame {offset = 4, offset adjust = 0, size = 4, size adjust = 0}
        memory {offset = 0, size = 4}
    argument 2: -------- -------- -------- --------
        type encoding (@) '@'
        flags {isObject}
        modifiers {}
        frame {offset = 8, offset adjust = 0, size = 4, size adjust = 0}
        memory {offset = 0, size = 4}

这篇关于iOS的iOS NSMethodSignature(或编码)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆