This is primarily a curiosity, I’m not really sure what’s the practical use of this but here goes.
Since blocks are also Objective-C objects, is it possible to check their type? That is, does it respond to the isKindOfClass: message and how to use that message with respect to blocks?
My naive thought that it’s probably like this:
-(void) aMethod {
typedef int (^BlockA)(int x, int y);
id blockVar = ...; // get a block from somewhere
if([blockVar isKindOfClass:BlockA]) {
BlockA blockVarA = blockVar;
int result = blockVarA(1,2);
}
}
The code above probably won’t work. But if it is possible to check a block’s type, what is the correct way to do it?
Can do, kinda sorta.
But first, let’s disambiguate.
-[NSObject isKindOfClass:]can tell you it’s a block, and that’s about it. E.g. I believe this line of code — ostensibly & unfortunately A BAD IDEA — will return YES for blocks on present Lion & iOS 5.x:That won’t help you distinguish the block’s function signature.
But it can be done, by snagging the signature from the block’s documented internal struct. Code follows for an example OS X command-line app, much of which ripped from Mike Ash’s MABlockClosure (great detailed explanation). (UPDATE: Github project CTObjectiveCRuntimeAdditions also apparently provides library code for just this purpose.)
Run this and you should get something like:
The numbers in the signature (I’m told they are offsets) can be stripped for simpler
i@?@.The signature is in the @encode format, which isn’t perfect (e.g. most objects map to same
@), but should afford you some ability to distinguish blocks with different signatures at runtime.While it’s not documented in the Apple link, my testing points to
@?being the code for a block type, which makes sense of the signature above. I found a clang-developers discussion on this issue which seems to back this up.