1) This answer talks about how to grab the signature of a block. Here's the relevant code:
static const char *BlockSig(id blockObj)
{
struct Block *block = (void *)blockObj;
struct BlockDescriptor *descriptor = block->descriptor;
int copyDisposeFlag = 1 << 25;
int signatureFlag = 1 << 30;
assert(block->flags & signatureFlag);
int index = 0;
if(block->flags & copyDisposeFlag)
index += 2;
return descriptor->rest[index];
}
It's really not ideal, since you just get the @encode
string of the signature, which looks like this: @"i16@?0@8"
. I'd love to see if someone has a better approach.
2) You can definitely cast blocks to and from type id
:
typedef void(^MyBlockType)(void);
id aBlock = ^ { };
((MyBlockType)aBlock)();
Of course, if you cast to the wrong block type, you'll end up with undefined behavior.