Primeiro, não tenho certeza se realmente entendo o que é um seletor. Pelo que entendi, é o nome de um método, e você pode atribuí-lo a uma classe do tipo 'SEL' e executar métodos como respondToSelector para verificar se o destinatário implementa esse método. Alguém pode oferecer uma explicação melhor?
Em segundo lugar, até este ponto, tenho o seguinte código:
NSString *thing = @"Hello, this is Craig";
SEL sel = @selector(lowercaseString:);
NSString *lower = (([thing respondsToSelector:sel]) ? @"YES" : @"NO");
NSLog (@"Responds to lowercaseString: %@", lower);
if ([thing respondsToSelector:sel]) //(lower == @"YES")
NSLog(@"lowercaseString is: %@", [thing lowercaseString]);
No entanto, embora thing
seja claramente um tipo de NSString e deva responder a lowercaseString, não posso obter o 'respondsToSelector' condicional para retornar "YES" ...
objective-c
selector
Craig
fonte
fonte
Respostas:
Você precisa ter muito cuidado com os nomes dos métodos. Nesse caso, o nome do método é apenas "
lowercaseString
", não "lowercaseString:
" (observe a ausência de dois pontos). É por isso que você estáNO
retornando, porque osNSString
objetos respondem àlowercaseString
mensagem, mas não alowercaseString:
mensagem.Como você sabe quando adicionar dois pontos? Você adiciona dois pontos ao nome da mensagem se você adicionar dois pontos ao chamá-lo, o que acontece se houver um argumento. Se receber zero argumentos (como é o caso
lowercaseString
), não haverá dois pontos. Se for necessário mais de um argumento, você deverá adicionar os nomes extras dos argumentos juntamente com seus dois pontos, como emcompare:options:range:locale:
.Você também pode consultar a documentação e observar a presença ou ausência de dois pontos à direita.
fonte
Seletores são uma maneira eficiente de referenciar métodos diretamente no código compilado - o compilador é o que realmente atribui o valor a um SEL.
Outros já cobriram a segunda parte do seu q, o ':' no final corresponde a uma assinatura diferente da que você está procurando (nesse caso, essa assinatura não existe).
fonte
Isso é porque você quer
@selector(lowercaseString)
, não@selector(lowercaseString:)
. Há uma diferença sutil: o segundo implica um parâmetro (observe os dois pontos no final), mas- [NSString lowercaseString]
não aceita um parâmetro.fonte
Nesse caso, o nome do seletor está errado. Os dois pontos aqui fazem parte da assinatura do método; isso significa que o método usa um argumento. Eu acredito que você quer
fonte
O método do NSString é
lowercaseString
(0 argumentos), nãolowercaseString:
(1 argumento).fonte
Não pense nos dois pontos como parte do nome da função, pense nele como um separador; se você não tiver nada para separar (sem valor para a função), não precisará dele.
Não sei por que, mas todas essas coisas OO parecem estranhas aos desenvolvedores da Apple. Eu sugiro fortemente pegar o Visual Studio Express e brincar com isso também. Não porque um seja melhor que o outro, é apenas uma boa maneira de analisar os problemas de design e as formas de pensar.
Gostar
É sempre bom olhar para um problema de maneiras diferentes e a programação é o quebra-cabeça definitivo.
fonte
Pelo meu entendimento da documentação da Apple, um seletor representa o nome do método que você deseja chamar. O bom dos seletores é que você pode usá-los nos casos em que o método exato a ser chamado varia. Como um exemplo simples, você pode fazer algo como:
fonte
Conforme documentos da apple: https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html
Exemplo: (lldb) breakpoint --set selector viewDidLoad
Isso definirá um ponto de interrupção em todas as implementações do viewDidLoad no seu aplicativo. Portanto, o seletor é uma espécie de identificador global para um método.
fonte