2012-08-25 24 views
5

Ho seguito un certo numero di esercitazioni e sto cadendo da solo. Qualcuno può aiutare, per favore?Comprendere il "sé" e impostarlo su super

Ho il seguente init, che è un metodo di istanza.

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

    if (self) { 
     score = s; 

    } 

    return self; 
} 

Ora la lettura attraverso il codice ho impostato l'auto al super init, quindi auto è ora indicando al super. Quindi controllo se self è valido e imposta il punteggio uguale al valore che ho inviato sul mio InitWIthScore. Ho ottenuto questo finora.

Ma ora ritorno auto che indica il super, quindi come posso restituire la mia sottoclasse?

Quindi, diciamo che qualcuno chiama la mia classe che passa in 100, il mio codice restituisce il super non la classe, quindi come funziona? In che modo il codice chiamante ha un valore di 100 nel punteggio?

naturalmente, sì, funziona ma non ho idea del perché :-(

risposta

5

Questo costrutto consente all'inizializzatore (sia l'inizializzatore super che quello che si sta scrivendo) di non riuscire - nil viene restituito se l'oggetto non può essere inizializzato. Questo è anche il motivo per cui si controlla nel proprio init dopo aver chiamato super.

Entrambe self e super puntano alla stessa struttura dati in memoria, ovvero l'oggetto che è stato assegnato.La differenza è nella semantica linguistica di questi puntatori speciali:

Quando si utilizza self, il compilatore Objective-C avvierà il metodo e la risoluzione di sovraccarico sul tipo corrente.

Quando si utilizza super, il compilatore Objective-C avvierà il metodo e la risoluzione di sovraccarico nel tipo super immediato della classe. In altre parole, super è solo semantica per poter chiamare un metodo nella tua super classe anche se esiste lo stesso metodo nella tua classe corrente.

In altre parole (leggermente semplificata), super tratta la posizione di memoria come se fosse un'istanza della classe super (ad esempio, il tipo che si sottoclasse, spesso NSObject), mentre self tratta la posizione di memoria come un puntatore regolare per la tipo che hai definito.

Se si stampa super e self nel debugger, si vedrà che puntano alla stessa posizione di memoria.

+0

fantastico !, questo è quello che stavo cercando .. Così me stesso in me :-) questo è buono, ma super anche in me? anche se super sarebbe la superclasse? cioè NSObject? – Martin

+0

quindi self = [super init]; ora self è uguale alla mia super classe di NSObject, o è uguale a me ma questo è dove mi confondo, arrivando a formare uno sfondo .net/java. Se chiamo la mia super classe e faccio un init allora il super è in realtà nsobject non è lo – Martin

+0

@ Martin, ho aggiornato la risposta un po ', spero che chiarisca. Se hai una classe 'Foo' che eredita' NSObject' allora 'Foo' è anche un' NSObject' - la is-a. 'self' e' super' puntano alla stessa memoria ma la considerano diversa quando si risolve. – driis

3

L'intera chiamata la creazione di oggetti sembra un po 'come questo:

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

Ora la prima cosa che succede è chiamare [SomeClass alloc]. Ciò creerà una struttura per SomeClass in memoria e restituire un puntatore ad esso. Segue la roba inizializzazione, dove self è il puntatore del passaggio precedente. Pertanto self punti ad un oggetto della classe SomeClass.

L'assegnazione sembra un po 'strano, però:

self = [super init]; 

Nella maggior parte dei casi [super init] non cambierà self, sarà solo restituirà il puntatore creato da [SomeClass alloc]. Ma il modello di assegnazione consente due opzioni extra:

  1. La superclasse init può segnalare un errore di costruzione ritornando nil, nel qual caso tutte le seguenti inizializzatori bail out e si ottiene un oggetto nil.

  2. L'inizializzatore della superclasse può decidere di restituire un puntatore self diverso, ad esempio se viene eseguita una memorizzazione nella cache elaborata. Il puntatore dovrebbe puntare nuovamente a un oggetto di tipo SomeClass, in modo che il codice funzioni (è possibile accedere a score ecc.).

Suggerisco di leggere The How and Why of Cocoa Initializers di Mike Ash. E sì, è molto bello capire che self e super puntano entrambi allo stesso oggetto, come notato da Driis.

+0

Penso che voglia sapere perché lo fa comunque. La ragione di ciò è che '[super init]' può restituire un puntatore diverso, ad esempio 'nil' se non riesce a inizializzarsi. – JustSid

+0

Hi zoul, sì ho la creazione dell'oggetto e capisco cosa non capisco (vedi lo snippet di codice in questione sopra) è che in initiWithScore, il sé viene assegnato a [super init] quindi ora ha il super e restituisce questo super al client chiamante, quindi come fa il client chiamante (il tuo codice) ad avere il contenuto di "SomeClass" quando è stato restituito super. – Martin

+0

Grazie per il link Zoul, rende una lettura interessante. – Martin

Problemi correlati