Sintaxe de método em Objective-C

176

Alguém pode explicar essa sintaxe de declaração de método para mim? Nesta função, o número de linhas de um UIPickerView (UI de slot machine no iPhone) está sendo retornado. Pelo meu entendimento, o método é chamado 'pickerView ' e retorna um NSInteger.

Ele passa um ponteiro para o UIPickerview chamado ' pickerView' ... primeiro, por que o método é chamado com o mesmo nome que o parâmetro?

Em seguida, há o parâmetro NSInteger chamado component que nos diz para qual componente estamos contando as linhas. A lógica para decidir qual está no corpo do método.

O que é ' numberOfRowsInComponent? Parece descrever o valor que estamos retornando, mas está no meio dos parâmetros.

- (NSInteger) pickerView:(UIPickerView *)pickerView 
 numberOfRowsInComponent:(NSInteger)component
{
    if (component == kStateComponent)
        return [self.states count];

    return[self.zips count];
}
Craig
fonte

Respostas:

358

Os métodos Objective-C são projetados para serem auto-documentados e tomam emprestado da rica tradição do Smalltalk.

Vou tentar explicar o que você tem aqui -(NSInteger) pickerView:(UIPickerView*)pickerView numberOfRowsInComponent:(NSInteger)component.

  • - (NSInteger)
    Esta primeira parte indica que este é um método de instância do Objective C que retorna um objeto NSInteger. o -(traço) indica que este é um método de instância , onde a +indicaria que este é um método de classe . O primeiro valor entre parênteses é o tipo de retorno do método.

  • pickerView:
    Esta parte faz parte do nome da mensagem . O nome completo da mensagem neste caso é pickerView:numberOfRowsInComponent:. O tempo de execução do Objective-C pega essas informações do método e as envia para o receptor indicado. Em C puro, isso seria semelhante
    NSInteger pickerView(UIPickerView* pickerView, NSInteger component). No entanto, como esse é o Objective-C, informações adicionais são compactadas no nome da mensagem.

  • (UIPickerView*)pickerView
    Esta parte faz parte da entrada . A entrada aqui é do tipo UIPickerView*e tem um nome de variável local de pickerView.

  • numberOfRowsInComponent:
    Esta parte é a segunda parte do nome da mensagem . Como você pode ver aqui, os nomes das mensagens são divididos para ajudar a indicar quais informações você está passando para o destinatário. Assim, se fosse de uma mensagem meuObjeto objeto com as variáveis foo e bar, eu tipo:
    [myObject pickerView:foo numberOfRowsInComponent:bar];
    em oposição ao estilo C ++:
    myObject.pickerView(foo, bar);.

  • (NSInteger)component
    Esta é a última parte da entrada . a entrada aqui é do tipo NSIntegere possui um nome de variável local do componente.

locriani
fonte
18
+1 para uma ótima resposta. Eu sugeriria mudar "factory" para "class" em seu primeiro ponto, já que o "+" indica oficialmente um método de classe. Acontece que muitos métodos "+" são métodos de fábrica, mas essa não é a definição adequada.
275109
2
Obrigado! Uma pergunta adicional: se você enviar uma mensagem para um objeto myObject com as variáveis ​​foo e bar, como você mostrou: [myObject pickerView: foo numberOfRowsInComponent: bar]; PickerView se refere ao nome ou parâmetro do método?
Craig
2
Nem. É bom estilo referir-se ao nome do método AND parâmetro, mas o nome completo do método é realmente pickerView: numberOfRowsInComponent :. Se você tentasse chamar o pickerView:, você receberia um erro de tempo de execução, pois o método não existiria.
31510 locriani
1
Deixe-me esclarecer sobre isso: a parte pickerView: por si só DEVE referir-se ao seguinte parâmetro, para seguir um bom estilo de codificação. No entanto, é apenas 1/2 do nome do método. Um exemplo melhor pode ser [myObject setX: foo Y: bar], em que o método é setX: Y :.
31510 locriani
1
Sei que essa resposta é antiga, mas estou vivendo em um mundo .NET nos últimos anos. Sou iniciante no Objetivo C e faço a transição de um mundo da Web para o setor móvel. Gostaria de agradecer por uma explicação tão bem documentada que é tão relevante para a pergunta. 1
d3v1lman1337
52

No Objective-C, o nome de um método é composto por todas as partes da declaração que não são argumentos e tipos. O nome desse método seria, portanto:

pickerView:numberOfRowsInComponent:

O método seria equivalente a uma função no estilo C com a seguinte aparência:

edit: (com agradecimentos a Jarret Hardie ):

NSInteger pickerViewNumberOfRowsInComponent(UIPickerView * pickerView, NSInteger component)
e.James
fonte
1
+1 - boa descrição curta. Às vezes eu encontrar a lâmpada passa para as pessoas se você escrever o equivalente C-estilo como "NSInteger pickerViewNumberOfRowsInCompoent (UIPickerView * pickerView, componente NSInteger)
Jarret Hardie
Eu gosto da sua explicação, reescrever em C é muito melhor.
Lcc
30

Além das respostas anteriores, gostaria apenas de dizer que os métodos Objective-C (ou mensagens, se preferir) têm nomes de parâmetros externos e internos .

Então, neste caso:

- (NSInteger) pickerView:(UIPickerView *)pickerView 
 numberOfRowsInComponent:(NSInteger)component

numberOfRowsInComponenté o nome externo , aquele que você usaria ao chamar esse método de fora.

E componenté o nome interno do parâmetro, aquele que você usa para se referir ao parâmetro de dentro do método.

Espero que isso esclareça um pouco.

Karolis
fonte
1
De acordo com sua descrição, o nome do método pode ser considerado como o nome externo do primeiro parâmetro. Isso também se encaixa no comentário de wilczarz abaixo.
Jake
Porra, acho esta resposta tão incorreta. Não há nada como um nome externo / interno de parâmetros. É o identificador TYPE e VARIABLE. Eu me pergunto por que todo mundo tenta definir o ObjC como uma linguagem natural, é tão antinatural em todos os aspectos. É uma linguagem, é isso, vamos apenas aprender sem usar palavras bonitas ao seu redor.
Siddharth
Os argumentos podem ter nomes internos / externos. Isso é verdade.
lcc 21/07
21

Parece-me que as assinaturas do método Objective-C são mais como sentenças. Cada parâmetro merece uma parte no nome do método. Por exemplo, em C, poderíamos ter um método ( setPersonData ) para definir algumas informações sobre pessoa:

void setPersonData( char* name, int age, float height ) {

e em Objective-C, o método seria mais descritivo ( setPersonName: andAge: andHeight:) , como

- (void) setPersonName: (char *)name andAge:(int)age andHeight:(float)height {
wilczarz
fonte
8
E por que setPersonalData (char * andName, int alsoAge, float alsoHeight) não faria sentido? É tudo sobre o que você entende sobre a sintaxe, nada sobre a intenção dos designers de objc serem inteligentes aqui. que acabou de adicionar um monte de mais sintaxe que francamente não faz qualquer sentido .. :)
Siddharth
5
Você entendeu mal a resposta que eu tenho medo. setPersonalData (char * andName, int alsoAge, float alsoHeight) é uma assinatura, não uma invocação. A invocação dessa função seria setPersonData ("Tom", 25, 175) - e isso não diz muito, não é? A chamada Obj-C ficaria assim: [pessoa setPersonName: @ "Tom" e Idade: 25 e Altura: 175];
wilczarz
3
Agora que penso nisso, minha resposta é mais uma queixa do que uma declaração. Eu não poderia concordar mais.
Siddharth