iOS Blocks introspection
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.
I think the problem for number 2 is that blocks are named as part of the type definition, e.g.
void (^blockName)(void) = ^{};
A workaround is to define a generic block type:
typedef void(^BlockType)(void);BlockType myBlock = ^{};myBlock();
edit: pointed out by @neilco, a much simpler way using dispatch block types (which return nothing and accept no arguments):
dispatch_block_t myBlock = ^{};myBlock();