Methodensyntax in Objective-C

176

Kann mir jemand diese Syntax der Methodendeklaration erklären? In dieser Funktion wird die Anzahl der Zeilen eines UIPickerView (Spielautomaten-Benutzeroberfläche auf dem iPhone) zurückgegeben. pickerViewNach meinem Verständnis heißt die Methode ' ' und gibt eine NSInteger zurück.

Es übergibt einen Zeiger auf die UIPickerview mit dem Namen ' pickerView' ... zuerst, warum heißt die Methode den gleichen Namen wie der Parameter?

Als nächstes gibt es den NSInteger-Parameter namens component, der uns sagt, für welche Komponente wir die Zeilen zählen. Die Logik, um zu entscheiden, welche sich im Hauptteil der Methode befindet.

Was ist ' numberOfRowsInComponent? Es scheint den Wert zu beschreiben, den wir zurückgeben, aber es befindet sich in der Mitte der Parameter.

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

    return[self.zips count];
}
Craig
quelle

Antworten:

358

Objective-C-Methoden sind so konzipiert, dass sie sich selbst dokumentieren, und sie basieren auf der reichen Tradition von Smalltalk.

Ich werde versuchen zu erklären, was Sie hier haben -(NSInteger) pickerView:(UIPickerView*)pickerView numberOfRowsInComponent:(NSInteger)component.

  • - (NSInteger)
    Dieser erste Abschnitt gibt an, dass dies eine Objective C- Instanzmethode ist, die ein NSInteger-Objekt zurückgibt. Der -(Bindestrich) gibt an, dass dies eine Instanzmethode ist, wobei a +angibt, dass dies eine Klassenmethode ist. Der erste Wert in Klammern ist der Rückgabetyp der Methode.

  • pickerView:
    Dieser Teil ist Teil des Nachrichtennamens . Der vollständige Nachrichtenname lautet in diesem Fall pickerView:numberOfRowsInComponent:. Die Objective-C-Laufzeit nimmt diese Methodeninformationen und sendet sie an den angegebenen Empfänger. In reinem C würde dies so aussehen
    NSInteger pickerView(UIPickerView* pickerView, NSInteger component). Da dies jedoch Objective-C ist, werden zusätzliche Informationen in den Nachrichtennamen gepackt.

  • (UIPickerView*)pickerView
    Dieser Teil ist Teil der Eingabe . Die Eingabe hier ist vom Typ UIPickerView*und hat den lokalen Variablennamen pickerView.

  • numberOfRowsInComponent:
    Dieser Teil ist der zweite Teil des Nachrichtennamens . Wie Sie hier sehen können, werden die Nachrichtennamen aufgeteilt, um anzugeben, welche Informationen Sie an den Empfänger weitergeben. Wenn ich also ein Objekt myObject mit den Variablen foo und bar benachrichtigen würde, würde ich Folgendes eingeben:
    [myObject pickerView:foo numberOfRowsInComponent:bar];
    im Gegensatz zum C ++ - Stil :
    myObject.pickerView(foo, bar);.

  • (NSInteger)component
    Dies ist der letzte Teil der Eingabe . Die Eingabe hier ist vom Typ NSIntegerund hat einen lokalen Variablennamen der Komponente.

locriani
quelle
18
+1 für eine gute Antwort. Ich würde vorschlagen, in Ihrem ersten Punkt "factory" in "class" zu ändern, da das "+" offiziell eine Klassenmethode angibt. Es kommt einfach so vor, dass viele "+" - Methoden Factory-Methoden sind, aber das ist nicht die richtige Definition.
e.James
2
Vielen Dank! Eine zusätzliche Frage: Wenn Sie ein Objekt myObject mit den Variablen foo und bar wie folgt anzeigen würden: [myObject pickerView: foo numberOfRowsInComponent: bar]; Bezieht sich pickerView auf den Methodennamen oder -parameter?
Craig
2
Weder. Es ist ein guter Stil, sich sowohl auf den Methodennamen als auch auf den Parameter zu beziehen, aber der vollständige Methodenname lautet tatsächlich pickerView: numberOfRowsInComponent:. Wenn Sie versuchen würden, pickerView: aufzurufen, würden Sie einen Laufzeitfehler erhalten, da die Methode nicht vorhanden wäre.
Locriani
1
Lassen Sie mich das klarstellen: Der Teil pickerView: sollte sich auf den folgenden Parameter beziehen, um einem guten Codierungsstil zu folgen. Es ist jedoch nur die Hälfte des Methodennamens. Ein besseres Beispiel könnte [myObject setX: foo Y: bar] sein, wobei die Methode setX: Y: ist.
Locriani
1
Ich weiß, dass diese Antwort alt ist, aber ich lebe seit einigen Jahren in einer .NET-Welt. Ich bin neu in Objective C und wechsle von einer Webwelt zur Mobilbranche. Ich möchte mich bei Ihnen für eine so gut dokumentierte Erklärung bedanken, die für die Frage so relevant ist. +1
d3v1lman1337
52

In Objective-C besteht der Name einer Methode aus allen Teilen der Deklaration, die keine Argumente und Typen sind. Der Name dieser Methode wäre daher:

pickerView:numberOfRowsInComponent:

Die Methode würde einer C-Funktion entsprechen, die wie folgt aussieht:

edit: (danke an Jarret Hardie ):

NSInteger pickerViewNumberOfRowsInComponent(UIPickerView * pickerView, NSInteger component)
James
quelle
1
+1 - schöne kurze Beschreibung. Manchmal finde ich, dass die Glühbirne für Leute eingeschaltet ist, wenn Sie das C-Äquivalent als "NSInteger pickerViewNumberOfRowsInCompoent (UIPickerView * pickerView, NSInteger-Komponente)
Jarret Hardie
Ich mag deine Erklärung, in C umzuschreiben ist viel besser.
lcc
30

Zusätzlich zu den vorherigen Antworten möchte ich nur sagen, dass Objective-C-Methoden (oder Nachrichten, wenn Sie dies bevorzugen) externe und interne Parameternamen haben.

Also in diesem Fall:

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

numberOfRowsInComponentist der externe Name, den Sie verwenden würden, wenn Sie diese Methode von außen aufrufen.

Und componentist der interne Name des Parameters, den Sie verwenden, um auf den Parameter innerhalb der Methode zu verweisen.

Hoffe das klärt es ein bisschen auf.

Karolis
quelle
1
Entsprechend Ihrer Beschreibung kann der Methodenname als externer Name des ersten Parameters betrachtet werden. Dies passt auch zu Wilczarz 'Kommentar unten.
Jake
Verdammt, ich finde diese Antwort so falsch. Es gibt nichts Schöneres als einen externen / internen Namen von Parametern. Es ist der TYP und die VARIABLE-Kennung. Ich frage mich, warum jeder so sehr versucht, ObjC als natürliche Sprache zu definieren, es ist einfach so unnatürlich in all seinen Wegen. Es ist eine Sprache, das ist es, wir können sie einfach lernen, ohne ausgefallene Wörter zu verwenden.
Siddharth
Argumente können interne / externe Namen haben. Das ist richtig.
lcc
21

Es scheint mir, dass Signaturen der Objective-C-Methode eher wie Sätze sind. Jeder Parameter verdient einen Teil im Methodennamen. In C könnten wir beispielsweise eine Methode ( setPersonData ) zum Festlegen einiger Informationen über die Person haben:

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

und in Objective-C wäre die Methode aussagekräftiger ( setPersonName: andAge: andHeight :) , wie z

- (void) setPersonName: (char *)name andAge:(int)age andHeight:(float)height {
wilczarz
quelle
8
Und warum sollte setPersonalData (char * und Name, int alsoAge, float alsoHeight) keinen Sinn ergeben? Es geht nur darum, was Sie über die Syntax verstehen, nicht um die Absicht von Objektdesignern, hier schlau zu sein. Sie haben nur eine Menge mehr Syntax hinzugefügt, die ehrlich gesagt keinen Sinn ergab. :)
Siddharth
5
Sie haben die Antwort falsch verstanden, fürchte ich. setPersonalData (char * und Name, int alsoAge, float alsoHeight) ist eine Signatur, kein Aufruf. Der Aufruf dieser Funktion wäre setPersonData ("Tom", 25, 175) - und das sagt nicht viel aus, oder? Der Obj-C-Aufruf würde folgendermaßen aussehen: [person setPersonName: @ "Tom" andAge: 25 andHeight: 175];
Wilczarz
3
Jetzt, wo ich darüber nachdenke, ist meine Antwort eher eine Beschwerde als eine Aussage. Ich konnte nicht mehr zustimmen.
Siddharth