実行時に特定のブロックの引数の数と引数の種類を確認する方法が必要です(現在作成しているオブジェクトマッピングライブラリにこれが必要です。文字列形式の値をセレクターにマッピングしています。ブロックにも同じものが必要です) 。
以下の例のコードを試しましたが、何らかの理由で機能せず、文字列の説明にnilを返します。
実行時にブロック署名を評価する方法を知っていますか(iPhoneアプリストアの提出に適しています)?
これは私が使用するコードです:
struct BlockDescriptor {
unsigned long reserved;
unsigned long size;
void *rest[1];
};
struct Block {
void *isa;
int flags;
int reserved;
void (*invoke)(struct __block_literal_1 *);
struct BlockDescriptor *descriptor;
};
enum {
BLOCK_HAS_COPY_DISPOSE = (1 << 25),
BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code
BLOCK_IS_GLOBAL = (1 << 28),
BLOCK_HAS_STRET = (1 << 29), // IFF BLOCK_HAS_SIGNATURE
BLOCK_HAS_SIGNATURE = (1 << 30),
};
static const char *BlockSig(id blockObj)
{
struct Block *block = (void *)blockObj;
struct BlockDescriptor *descriptor = block->descriptor;
assert(block->flags & BLOCK_HAS_SIGNATURE);
int index = 0;
if(block->flags & BLOCK_HAS_COPY_DISPOSE)
index += 2;
return descriptor->rest[index];
}
-(NSString*)signatureForBlock:(id)block {
NSString* sig = [NSString stringWithUTF8String:BlockSig(block)];
sig = [sig substringFromIndex:1]; // remove c
NSArray* components = [sig componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"0123456789?"]];
sig = [components componentsJoinedByString:@""];
return sig;
}
次に、次のことを行います。
NSString * (^block)(int, NSArray *) = ^NSString * (int i, NSArray * a){
return @"Oh, yeah!";
};
NSLog(@"signature %s", BlockSig(block)); // ==> this returns null
出典: Objective-Cブロックタイプを確認していますか? https://github.com/mikeash/MABlockForwarding/blob/master/main.m