Подтвердить что ты не робот

Как проверить объект как вид блока или нет

Как мы можем идентифицировать какой-либо конкретный объект как вид блока или нет?

например,

NSSet *set =[NSSet setWithObjects:
             @"name1",
             @"name2",
             [^{ /* ..... some code */ } copy],
             nil];

Как узнать, какой объект из набора является своего рода блоком?

4b9b3361

Ответ 1

Существует более безопасный способ определить, является ли что-то блоком, фактически не используя private api или не создавая класс с использованием имени частной строки:

- (BOOL)isBlock:(id)item {
    id block = ^{};
    Class blockClass = [block class];
    while ([blockClass superclass] != [NSObject class]) {
        blockClass = [blockClass superclass];
    }
    return [item isKindOfClass:blockClass];
}

Ответ 2

Оберните свой блок в собственный класс:

BlockWrapper *blockWrapper = [BlockWrapper wrapperWithBlock:^{ … }];

Проверьте тип и извлеките фактический блок:

if ([obj isKindOfClass:[BlockWrapper class]]) {
    codeBlock = [(BlockWrapper*)obj block];
}

Ответ 3

Нет поддерживаемого способа сделать это. Вы должны следить за тем, какие объекты являются блоками, и каковы их подписи типов.

Есть ли у вас практический прецедент для набора смешанных строк и блоков?

Ответ 4

Возможно, но я бы не рекомендовал это делать, потому что NSBlock не является публичным классом, и его имя может измениться в будущем:

if ([obj isKindOfClass:NSClassFromString(@"NSBlock")]) {
    NSLog(@"It a block!");
}

Ответ 5

Если у вас есть только строки и блоки, просто отметьте ![thing isKindOfClass:[NSString class]]. т.е. инвертировать ваш тест.

Аналогично, если у вас есть строки, числа и блоки, проверьте, что thing не является строкой или числом, и в этом случае он должен (по вычету) быть блоком. Либо это, либо ваша программа неверна и сбой.

Ответ 6

Я полагаю, что ![thing isKindOfClass:[NSObject class]], хотя и не является технически корректным (вам не нужно подкласса NSObject), вероятно, вы захотите, что хотите.