Como especificar o objeto de bloco / predicado exigido pelo KeySoFentResPassingTest do NSDictionary?
-
27-09-2019 - |
Pergunta
Para aprender (ainda não prático - ainda), gostaria de usar o seguinte método em um nsdictionary para me devolver um conjunto de chaves que possuem valores usando um teste que eu defini. Infelizmente, não tenho idéia de como especificar o predicado.
NSDictionary keysOfEntriesPassingTest:
- (NSSet *)keysOfEntriesPassingTest:(BOOL (^)(id key, id obj, BOOL *stop))predicate
Digamos, por exemplo, todos os meus valores são nsurls, e eu gostaria de recuperar todos os URLs que estão na porta 8080. Aqui está minha facada em codificar isso - embora não faça sentido para mim que seria correto:
NSSet * mySet = [myDict keysOfEntriesPassingTest:^(id key, id obj, BOOL *stop) {
if( [[obj port] isEqual: [NSNumber numberWithInt: 8080]]) {
return key;
}]
E isso é porque eu recebo o seguinte erro do compilador:
tipos de ponteiro de bloco incompatíveis inicializando 'void (^) (struct objc_object *, struct objc_object *, bool *)', esperado 'bool (^) (struct objc_object *, struct objc_object *, bool *)'
o que estou perdendo? Eu apreciaria um ponteiro em alguns documentos que entram em mais detalhes sobre o "objeto de bloco" que o predicado deve ser.
Obrigado!
E este é o código que funciona:
NSSet *mySet = [myDict keysOfEntriesPassingTest:^(id key, id obj, BOOL *stop)
{
if ([[obj port] isEqual:[NSNumber numberWithInt: 8080]])
return YES;
else
return NO;
}];
Solução
O erro indica que seu bloco deve retornar um BOOL
, ao invés de id
. Verifique os documentos. Eu suspeito que você deve retornar YES
Se o par de chaves/obj passar o teste desejado.
Outras dicas
Uma pequena expansão na resposta de Barry ....
Um bloco é como um ponteiro de função com uma diferença importante. Um bloco inferirá o tipo de retorno das declarações de retorno contidas dentro ou Ele fornecerá uma mensagem de erro como a que você disse (o erro do compilador LLVM deve ser um pouco mais razoável).
Quando você escreveu:
NSSet * mySet = [myDict keysOfEntriesPassingTest:^(id key, id obj, BOOL *stop) {
if( [[obj port] isEqual: [NSNumber numberWithInt: 8080]]) {
return key;
}]
Considere isso como uma função:
BOOL bob(id key, id obj) {
if( [[obj port] isEqual: [NSNumber numberWithInt: 8080]]) {
return key;
}
}
Veja o problema? Existe um caminho de código que não retorna um valor e, portanto, o compilador reclamaria.