Как проверить объект как вид блока или нет
Как мы можем идентифицировать какой-либо конкретный объект как вид блока или нет?
например,
NSSet *set =[NSSet setWithObjects:
@"name1",
@"name2",
[^{ /* ..... some code */ } copy],
nil];
Как узнать, какой объект из набора является своего рода блоком?
Ответы
Ответ 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
), вероятно, вы захотите, что хотите.