Syntaxe de méthode en Objective-C

177

Quelqu'un peut-il m'expliquer cette syntaxe de déclaration de méthode? Dans cette fonction, le nombre de lignes d'un UIPickerView (UI de machine à sous sur l'iPhone) est renvoyé. D'après ce que je comprends, la méthode s'appelle « pickerView» et renvoie un NSInteger.

Il passe un pointeur vers l'UIPickerview appelé ' pickerView' ... d'abord, pourquoi la méthode s'appelle-t-elle le même nom que le paramètre?

Ensuite, il y a le paramètre NSInteger appelé component qui nous indique pour quel composant nous comptons les lignes. La logique pour décider lequel est dans le corps de la méthode.

Qu'est-ce que ' numberOfRowsInComponent? Il semble décrire la valeur que nous retournons, mais c'est au milieu des paramètres.

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

    return[self.zips count];
}
Craig
la source

Réponses:

359

Les méthodes Objective-C sont conçues pour être auto-documentées et elles empruntent à la riche tradition de Smalltalk.

Je vais essayer d'expliquer ce que vous avez ici, -(NSInteger) pickerView:(UIPickerView*)pickerView numberOfRowsInComponent:(NSInteger)component.

  • - (NSInteger)
    Cette première partie indique qu'il s'agit d'une méthode d' instance Objective C qui renvoie un objet NSInteger. le -(tiret) indique qu'il s'agit d'une méthode d' instance , où un +indiquerait qu'il s'agit d'une méthode de classe . La première valeur entre parenthèses est le type de retour de la méthode.

  • pickerView:
    Cette partie fait partie du nom du message . Le nom complet du message dans ce cas est pickerView:numberOfRowsInComponent:. Le runtime Objective-C prend ces informations de méthode et les envoie au récepteur indiqué. En pur C, cela ressemblerait à
    NSInteger pickerView(UIPickerView* pickerView, NSInteger component). Cependant, puisqu'il s'agit d'Objective-C, des informations supplémentaires sont intégrées dans le nom du message.

  • (UIPickerView*)pickerView
    Cette partie fait partie de l' entrée . L'entrée ici est de type UIPickerView*et a un nom de variable locale de pickerView.

  • numberOfRowsInComponent:
    Cette partie est la deuxième partie du nom du message . Comme vous pouvez le voir ici, les noms des messages sont divisés pour aider à indiquer les informations que vous transmettez au destinataire. Ainsi, si je devais un message un objet monObjet avec les variables foo et bar, je taperais:
    [myObject pickerView:foo numberOfRowsInComponent:bar];
    par opposition au style de C:
    myObject.pickerView(foo, bar);.

  • (NSInteger)component
    Ceci est la dernière partie de l' entrée . l'entrée ici est de type NSIntegeret a un nom de variable locale de composant.

Locriani
la source
18
+1 pour une excellente réponse. Je suggérerais de changer «usine» en «classe» dans votre premier point, puisque le «+» indique officiellement une méthode de classe. Il se trouve que de nombreuses méthodes "+" sont des méthodes d'usine, mais ce n'est pas la bonne définition.
e.James
2
Merci! Une question supplémentaire: Si vous deviez envoyer un message à un objet myObject avec les variables foo et bar comme vous l'avez montré: [myObject pickerView: foo numberOfRowsInComponent: bar]; PickerView fait-il référence au nom ou au paramètre de la méthode?
Craig
2
Ni. Il est judicieux de faire référence à la fois au nom de la méthode ET au paramètre, mais le nom complet de la méthode est en fait pickerView: numberOfRowsInComponent :. Si vous tentiez d'appeler pickerView :, vous recevriez une erreur d'exécution, car la méthode n'existerait pas.
locriani
1
Permettez-moi de clarifier cela: la partie pickerView: en elle-même DEVRAIT faire référence au paramètre suivant, pour suivre un bon style de codage. Cependant, ce n'est que la moitié du nom de la méthode. Un meilleur exemple peut être [myObject setX: foo Y: bar], où la méthode est setX: Y :.
locriani
1
Je sais que cette réponse est ancienne, mais je vis dans un monde .NET depuis quelques années. Je suis nouveau sur Objective C et je suis en train de passer d'un monde Web à l'industrie mobile. Je tiens à vous remercier pour cette explication si bien documentée et si pertinente à la question. +1
d3v1lman1337
52

En Objective-C, le nom d'une méthode est composé de toutes les parties de la déclaration qui ne sont pas des arguments et des types. Le nom de cette méthode serait donc:

pickerView:numberOfRowsInComponent:

La méthode serait équivalente à une fonction de style C qui ressemblerait à ceci:

edit: (avec merci à Jarret Hardie ):

NSInteger pickerViewNumberOfRowsInComponent(UIPickerView * pickerView, NSInteger component)
e.James
la source
1
+1 - belle courte description. Parfois, je trouve que l'ampoule est allumée pour les gens si vous écrivez l'équivalent de style C comme "NSInteger pickerViewNumberOfRowsInCompoent (UIPickerView * pickerView, NSInteger component)
Jarret Hardie
j'aime bien votre explication, réécrire en C c'est bien mieux.
lcc
30

Ajoutant aux réponses précédentes, je voudrais juste dire que les méthodes Objective-C (ou les messages si vous préférez) ont des noms de paramètres externes et internes .

Donc dans ce cas:

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

numberOfRowsInComponentest le nom externe , celui que vous utiliseriez pour appeler cette méthode de l'extérieur.

Et componentest le nom interne du paramètre, celui que vous utilisez pour faire référence au paramètre depuis l'intérieur de la méthode.

J'espère que cela clarifie un peu les choses.

Karolis
la source
1
Conformément à votre description, le nom de la méthode peut être considéré comme le nom externe du premier paramètre. Cela correspond également au commentaire de wilczarz ci-dessous.
Jake
Merde, je trouve cette réponse tellement incorrecte. Il n'y a rien de tel qu'un nom externe / interne de paramètres. C'est le TYPE et l'identifiant VARIABLE. Je me demande pourquoi tout le monde essaie si dur de définir ObjC comme un langage naturel, c'est tellement artificiel à tous égards. C'est une langue, c'est tout, permet de l'apprendre sans utiliser de mots fantaisistes autour d'elle.
Siddharth
Les arguments peuvent avoir des noms internes / externes. C'est vrai.
lcc
21

Il me semble que les signatures de la méthode Objective-C ressemblent plus à des phrases. Chaque paramètre mérite une partie dans le nom de la méthode. Par exemple, en C, nous pourrions avoir une méthode ( setPersonData ) pour définir des informations sur la personne:

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

et en Objective-C la méthode serait plus descriptive ( setPersonName: andAge: andHeight:) , comme

- (void) setPersonName: (char *)name andAge:(int)age andHeight:(float)height {
Wilczarz
la source
8
Et pourquoi setPersonalData (char * andName, int alsoAge, float alsoHeight) n'aurait pas de sens? Tout dépend de ce que vous comprenez sur la syntaxe, rien sur l'intention des concepteurs d'objc d'être intelligents ici. ils ont juste ajouté un tas de syntaxe supplémentaire qui n'avait franchement aucun sens .. :)
Siddharth
5
Vous avez mal compris la réponse, j'en ai peur. setPersonalData (char * andName, int alsoAge, float alsoHeight) est une signature, pas une invocation. L'appel de cette fonction serait setPersonData ("Tom", 25, 175) - et cela ne dit pas grand-chose? L'appel d'Obj-C ressemblerait à ceci: [person setPersonName: @ "Tom" andAge: 25 andHeight: 175];
wilczarz
3
Maintenant que j'y pense, ma réponse est plus une plainte qu'une déclaration. Je ne pourrais pas être plus d'accord.
Siddharth