iOS Blocks introspection iOS Blocks introspection objective-c objective-c

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();