I would like to know two things:
1- Is it possible by using objective-c introspection to know the return type of a block.
For example: int (^CountBlock)(NSArray *array)
I would like to know the type it will be returning is int
.
The second question is:
2- Can I hold a reference to a generic block? What I mean with this, is basically can I do something like id myBlock
and with this answer the first question.
What I tried
This kind of stuff is not possible:
id aBlock = ^{
NSString * aString = @"OMG";
return aString;
};
aBlock();
As the compiler sees that the id aBlock
is not a function or a function pointer.
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.