Можно сделать , своего рода сортировка.
Но сначала давайте устраним неоднозначность.-[NSObject isKindOfClass:]
могу сказать, что это блок, и это все.Например, я считаю, эта строка кода - якобы и, к сожалению, ПЛОХАЯ ИДЕЯ - вернет ДА для блоков на нынешнем Lion & iOS 5.x:
[myBlock isKindOfClass:NSClassFromString(@"NSBlock")]
Это не поможет вам отличить сигнатуру функции блока.
Но это можно сделать, поймав подпись из документированной внутренней структуры блока.Далее приведен код для примера приложения командной строки OS X, большая часть которого взята из MABlockClosure Майка Эша (великолепное подробное объяснение ).(ОБНОВЛЕНИЕ: проект Github CTObjectiveCRuntimeAdditions , очевидно, также предоставляет библиотечный код именно для этой цели.)
#import <Foundation/Foundation.h>
struct BlockDescriptor {
unsigned long reserved;
unsigned long size;
void *rest[1];
};
struct Block {
void *isa;
int flags;
int reserved;
void *invoke;
struct BlockDescriptor *descriptor;
};
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];
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
int (^block)(NSNumber *) = ^(NSNumber *num) {
NSLog(@"%@ %@", NSStringFromClass([num class]), num);
return [num intValue];
};
NSLog(@"signature %s", BlockSig(block));
NSLog(@"retval %d", (int)block([NSNumber numberWithInt:42]));
}
return 0;
}
Запустите это, и вы должны получить что-то вроде:
[58003:403] signature i16@?0@8
[58003:403] __NSCFNumber 42
[58003:403] retval 42
Числа в подписи (мне говорят, что они являются смещениями) можно упростить для упрощения i@?@
.
Подпись в формате @ encode , что не идеально (например, большинство объектов отображаются на одну и ту же @
), но должны предоставить вам некоторую возможность различать блоки с разными сигнатурами во время выполнения.
Хотя это не задокументировано в ссылке Apple, мои точки тестирования@?
- код для типа блока, который имеет смысл подписи выше.Я нашел clang-developers обсуждение по этому вопросу, которое, похоже, подтверждает это.