Składnia metody w Objective-C

176

Czy ktoś może mi wyjaśnić składnię deklaracji metody? W tej funkcji zwracana jest liczba wierszy UIPickerView (interfejs użytkownika automatu w telefonie iPhone). Z mojego rozumienia metoda nazywa się „ pickerView” i zwraca NSInteger.

Przekazuje wskaźnik do UIPickerview o nazwie „ pickerView” ... po pierwsze, dlaczego metoda ma taką samą nazwę jak parametr?

Następnie jest parametr NSInteger zwany komponentem, który mówi nam, dla którego składnika liczymy wiersze. Logika decydująca o tym, co znajduje się w treści metody.

Co to jest ' numberOfRowsInComponent? Wygląda na to, że opisuje wartość, którą zwracamy, ale znajduje się pośrodku parametrów.

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

    return[self.zips count];
}
Craig
źródło

Odpowiedzi:

358

Metody obiektywne-C mają na celu samodokumentowanie i zapożyczają z bogatej tradycji Smalltalk.

Postaram się wyjaśnić, co masz tutaj -(NSInteger) pickerView:(UIPickerView*)pickerView numberOfRowsInComponent:(NSInteger)component.

  • - (NSInteger)
    Ta pierwsza część wskazuje, że jest to metoda wystąpienia Objective C , która zwraca obiekt NSInteger. -(łącznik) wskazuje, że jest to przykład sposobu, w którym +wskazuje, że jest to klasa metody. Pierwsza wartość w nawiasach to zwracany typ metody.

  • pickerView:
    Ta część jest częścią nazwy wiadomości . Pełna nazwa wiadomość jest w tym przypadku pickerView:numberOfRowsInComponent:. Środowisko wykonawcze Objective-C pobiera te informacje o metodzie i wysyła je do wskazanego odbiorcy. W czystym C wyglądałoby to
    NSInteger pickerView(UIPickerView* pickerView, NSInteger component). Jednak ponieważ jest to Objective-C, dodatkowe informacje są umieszczane w nazwie wiadomości.

  • (UIPickerView*)pickerView
    Ta część jest częścią wejścia . Dane wejściowe tutaj są typu UIPickerView*i mają lokalną nazwę zmiennej pickerView.

  • numberOfRowsInComponent:
    Ta część to druga część nazwy wiadomości . Jak widać tutaj, nazwy wiadomości są podzielone, aby pomóc wskazać, jakie informacje są przekazywane do odbiorcy. Tak więc, gdybym wiadomość Wystąpił myObject obiekt z foo zmiennych i barze, chciałbym wpisać:
    [myObject pickerView:foo numberOfRowsInComponent:bar];
    w przeciwieństwie do stylu C ++:
    myObject.pickerView(foo, bar);.

  • (NSInteger)component
    To jest ostatnia część danych wejściowych . dane wejściowe tutaj są typu NSIntegeri mają lokalną nazwę zmiennej komponentu.

locriani
źródło
18
+1 za świetną odpowiedź. Sugerowałbym zmianę „fabryki” na „klasę” w pierwszym punkcie, ponieważ „+” oficjalnie wskazuje na metodę klasową. Tak się składa, że ​​wiele metod „+” to metody fabryczne, ale to nie jest właściwa definicja.
James,
2
Dzięki! Jedno dodatkowe pytanie: Gdybyś miał wysłać wiadomość do obiektu myObject ze zmiennymi foo i bar, tak jak pokazałeś: [myObject pickerView: foo numberOfRowsInComponent: bar]; Czy pickerView odwołuje się do nazwy metody lub parametru?
Craig,
2
Ani. Dobrze jest odwoływać się zarówno do nazwy metody ORAZ parametru, ale w rzeczywistości pełna nazwa metody to pickerView: numberOfRowsInComponent :. Gdybyś spróbował wywołać pickerView:, wystąpiłby błąd wykonania, ponieważ metoda nie istniałaby.
locriani,
1
Pozwól, że wyjaśnię to: sam pickerView: porcja POWINIEN odnosić się do następującego parametru, aby zachować dobry styl kodowania. Jednak jest to tylko 1/2 nazwy metody. Lepszym przykładem może być [myObject setX: foo Y: bar], gdzie metoda to setX: Y :.
locriani,
1
Wiem, że ta odpowiedź jest stara, ale od kilku lat żyję w świecie .NET. Jestem nowy w Objective C i przechodzę ze świata internetowego do branży mobilnej. Chciałbym podziękować za tak dobrze udokumentowane wyjaśnienie, które jest tak istotne dla pytania. +1
d3v1lman1337
52

W Objective-C nazwa metody składa się ze wszystkich części deklaracji, które nie są argumentami ani typami. Nazwa tej metody byłaby zatem następująca:

pickerView:numberOfRowsInComponent:

Metoda byłaby odpowiednikiem funkcji w stylu C, która wyglądałaby następująco:

edycja: (podziękowania dla Jarret Hardie ):

NSInteger pickerViewNumberOfRowsInComponent(UIPickerView * pickerView, NSInteger component)
e.James
źródło
1
+1 - ładny krótki opis. Czasami widzę, że żarówka zapala się dla ludzi, jeśli napiszesz odpowiednik w stylu C jako „NSInteger pickerViewNumberOfRowsInCompoent (UIPickerView * pickerView, składnik NSInteger)
Jarret Hardie
Podoba mi się twoje wyjaśnienie, przepisywanie w C jest znacznie lepsze.
lcc,
30

Dodając do poprzednich odpowiedzi, chciałbym tylko powiedzieć, że metody Objective-C (lub wiadomości, jeśli wolisz) mają nazwy parametrów zewnętrznych i wewnętrznych .

Więc w tym przypadku:

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

numberOfRowsInComponentjest nazwą zewnętrzną , tą, której użyłbyś podczas wywoływania tej metody z zewnątrz.

I componentjest wewnętrzną nazwą parametru, tą, której używasz do odniesienia się do parametru z wnętrza metody.

Mam nadzieję, że to trochę wyjaśnia.

Karolis
źródło
1
Zgodnie z twoim opisem, nazwa metody może być traktowana jako nazwa zewnętrzna pierwszego parametru. Pasuje to również do komentarza wilczarza poniżej.
Jake,
Cholera, uważam, że ta odpowiedź jest tak nieprawidłowa. Nie ma to jak zewnętrzna / wewnętrzna nazwa parametrów. Jest to TYP i identyfikator VARIABLE. Zastanawiam się, dlaczego wszyscy tak bardzo starają się zdefiniować ObjC jako język naturalny, po prostu tak nienaturalny pod każdym względem. To język, to wszystko, po prostu nauczmy się go bez używania wymyślnych słów.
Siddharth
Argumenty mogą mieć nazwy wewnętrzne / zewnętrzne. To prawda.
lcc,
21

Wydaje mi się, że podpisy metody Objective-C są bardziej jak zdania. Każdy parametr zasługuje na swoją część w nazwie metody. Na przykład w C moglibyśmy mieć metodę ( setPersonData ) do ustawienia pewnych informacji o osobie:

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

aw Objective-C metoda byłaby bardziej opisowa ( setPersonName: andAge: andHeight:) , jak

- (void) setPersonName: (char *)name andAge:(int)age andHeight:(float)height {
wilczarz
źródło
8
I dlaczego setPersonalData (char * andName, int alsoAge, float alsoHeight) nie miałoby sensu? Chodzi o to, co rozumiesz ze składni, nic o zamiarze, aby projektanci objc byli tutaj sprytni. po prostu dodali trochę więcej składni, która szczerze mówiąc nie miała żadnego sensu .. :)
Siddharth
5
Obawiam się, że źle zrozumiałeś odpowiedź. setPersonalData (char * andName, int alsoAge, float alsoHeight) to sygnatura, a nie wywołanie. Wywołanie tej funkcji byłoby setPersonData ("Tom", 25, 175) - i to niewiele mówi, prawda? Wywołanie Obj-C wyglądałoby następująco: [person setPersonName: @ "Tom" andAge: 25 andHeight: 175];
wilczarz 19.12.13
3
Teraz, kiedy o tym myślę, moja odpowiedź jest bardziej skargą niż oświadczeniem. Nie mogłem się bardziej zgodzić.
Siddharth