2012-08-25 7 views
5

Podążałem za kilkoma tutorialami i padam z siebie. Czy ktoś może pomóc?Zrozumienie "ja" i ustawienie siebie jako super

Mam następujący init, który jest metodą instancji.

- (id) initWithScore:(int) s { 
    self = [super init]; 

    if (self) { 
     score = s; 

    } 

    return self; 
} 

Teraz czytając kod ustawiam ja na super init, więc self wskazuje teraz na super. Następnie sprawdzam, czy wartość self jest poprawna, i ustaw wynik równy wartości przesłanej na moich InitialWIthScore. Mam to tak daleko.

Ale teraz zwracam siebie, co wskazuje na super, więc jak zwróciłem moją podklasę?

Stąd, powiedzmy, że ktoś wywołuje moją klasę przechodząc w 100, mój kod zwraca super nie klasę, więc jak to działa? W jaki sposób kod wywołujący ma wartość 100 w wyniku?

oczywiście, tak to działa, ale nie mam pojęcia dlaczego :-(

Odpowiedz

5

Konstrukcja ta umożliwia inicjalizator (zarówno inicjator super, jak i ten, który zapisujesz) w przypadku niepowodzenia - nil jest zwracana, jeśli nie można zainicjować obiektu. Dlatego ponależy sprawdzić po po wywołaniu super.

Zarówno self, jak i super wskazują na tę samą strukturę danych w pamięci, a mianowicie na przydzielony obiekt.Różnica polega na semantyce języka tych specjalnych wskaźników:

Gdy zostanie użyty self, kompilator Objective-C rozpocznie metodę i rozdzielczość przeciążania w bieżącym typie.

Gdy zostanie użyty , kompilator Objective-C uruchomi metodę i rozdzielczość przeciążenia w bezpośrednim super typie twojej klasy. Innymi słowy, super jest po prostu semantyką, aby móc wywołać metodę w twojej super klasie, nawet jeśli ta sama metoda istnieje w twojej obecnej klasie.

Innymi słowy (nieco uproszczony), super traktuje miejsce pamięci, jak gdyby był instancją super klasy (np czy rodzaj podklasy, często NSObject), natomiast self traktuje lokalizacji pamięci jako stałego wskaźnika do typ, który zdefiniowałeś.

Jeśli wydrukujesz super i self w debugerze, zobaczysz, że wskazują na to samo miejsce w pamięci.

+0

Świetne !, to właśnie szukałem .. Więc siebie we mnie :-) to jest dobre, ale też super we mnie? czy super byłabym superklasą? np. NSObject? – Martin

+0

so self = [super init]; teraz self jest równy mojej super klasie NSObject, lub jej równy mnie, ale tam, gdzie się mylę, pochodzący z tła .net/java. Jeśli zadzwonię do mojej super klasy i zrobię init, to super jest w rzeczywistości nsobject, nie jest to – Martin

+0

@Martin, zaktualizowałem odpowiedź nieco, mam nadzieję, że to wyjaśni. Jeśli masz klasę 'Foo', która dziedziczy' NSObject', to 'Foo' jest także' NSObject' - relacją is-a. 'self' i' super' wskazuje na tę samą pamięć, ale traktuje ją inaczej podczas rozwiązywania. – driis

3

Cała rozmowa tworzenie obiekt wygląda trochę tak:

SomeClass *foo = [[SomeClass alloc] initWithScore:100]; 

teraz pierwszą rzeczą, która się dzieje, nazywając [SomeClass alloc] To utworzy strukturę dla SomeClass w pamięci i zwróci na nią wskaźnik.Następnie jest to inicjalizacja, gdzie self jest wskaźnikiem z poprzedniego kroku, dlatego self wskazuje na obiekt klasy SomeClass.

Przyporządkowanie wygląda nieco dziwnie, ale:

self = [super init]; 

W większości przypadków [super init] nie zmieni self, będzie to po prostu wrócić wskaźnik stworzony przez [SomeClass alloc]. Ale wzór pozwala na przypisanie dwóch dodatkowych opcji:

  1. nadklasą init może sygnalizować błąd budowlany wracając nil, w którym to przypadku wszystkie następujące inicjalizatory wyskoczyć i masz nil obiekt.

  2. Inicjator superklasy może podjąć decyzję o zwróceniu innego wskaźnika self, na przykład, jeśli wykonywane jest skomplikowane buforowanie. Wskaźnik powinien ponownie wskazywać obiekt typu SomeClass, aby Twój kod działał (możesz uzyskać dostęp do score itd.).

Proponuję przeczytać The How and Why of Cocoa Initializers Mike'a Ash. I tak, bardzo dobrze jest zdać sobie sprawę z tego, że self i super wskazują na ten sam obiekt, co zauważyło driis.

+0

Myślę, że chce wiedzieć, dlaczego tak robi. Powodem tego jest to, że '[super init]' może zwrócić inny wskaźnik, na przykład 'nil', jeśli nie uda się go zainicjować. – JustSid

+0

Cześć zoul, tak, mam tworzenie obiektu i rozumiem to, czego nie rozumiem (patrz fragment kodu w powyższym pytaniu), to w initWithScore, self jest przypisywane do [super init], więc ma teraz super i zwraca to super do klienta wywołującego, a następnie w jaki sposób klient wywołujący (twój kod) ma zawartość "SomeClass", gdy super został zwrócony. – Martin

+0

Dzięki za link Zoul, robi interesującą lekturę. – Martin

Powiązane problemy