Seletores em Objective-C?

122

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 thingseja claramente um tipo de NSString e deva responder a lowercaseString, não posso obter o 'respondsToSelector' condicional para retornar "YES" ...

Craig
fonte
Você deseja ler a descrição do Seletor no site do desenvolvedor da Apple: Seletores .
Lothar
14
Stanford curso CS193P atribuição 1B? Eu tenho exatamente a mesma pergunta aqui! :)
Corstian Boerman

Respostas:

181

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á NOretornando, porque os NSStringobjetos respondem à lowercaseStringmensagem, mas não a lowercaseString: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 em compare:options:range:locale:.

Você também pode consultar a documentação e observar a presença ou ausência de dois pontos à direita.

Adam Rosenfield
fonte
12

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).

dstnbrkr
fonte
10

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.

mipadi
fonte
5

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

SEL sel = @selector(lowercaseString);
mkb
fonte
3

O método do NSString é lowercaseString(0 argumentos), não lowercaseString:(1 argumento).

Nicholas Riley
fonte
1

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

introspection = reflection
+ before functions/properties = static
- = instance level

É sempre bom olhar para um problema de maneiras diferentes e a programação é o quebra-cabeça definitivo.


fonte
0

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:

SEL selec;
if (a == b) {
selec = @selector(method1)
}
else
{
selec = @selector(method2)
};
[self performSelector:selec];
moonman239
fonte
0

Conforme documentos da apple: https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html

Um seletor é o nome usado para selecionar um método a ser executado para um objeto ou o identificador exclusivo que substitui o nome quando o código-fonte é compilado. Um seletor por si só não faz nada. Ele simplesmente identifica um método. A única coisa que torna o nome do método seletor diferente de uma sequência simples é que o compilador garante que os seletores sejam exclusivos. O que torna um seletor útil é que (em conjunto com o tempo de execução) ele atua como um ponteiro de função dinâmica que, para um determinado nome, aponta automaticamente para a implementação de um método apropriado para qualquer classe com a qual ele é usado. Suponha que você tenha um seletor para a execução do método e as classes Dog, Athlete e ComputerSimulation (cada uma delas implementou uma execução do método).

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.

Adrian
fonte