2009-05-27 16 views
9

Sono nuovo nell'obiettivo C e volevo solo ottenere un chiarimento generale su quando utilizzare un puntatore e quando non farlo, quando si dichiarano le variabili di istanza.Puntatori variabili di istanza Objective-C

L'esempio che mi viene in mente è UIView e BOOL. UIView Vorrei fare un puntatore, BOOL non lo farei (perché il compilatore mi ha urlato contro).

Qualsiasi consiglio generale sarebbe fantastico.

Cheers,

risposta

20

se si tratta di un oggetto, si utilizza la notazione puntatore. Tutti i tipi di c (int, BOOL, lungo, ecc) non sono oggetti, e quindi si utilizza solo un puntatore se si desidera un puntatore alla loro posizione di memoria:

NSObject *obj; 
UIView<Protocol> *obj; 
int integerVar; 
BOOL isTrue; 

Un caso particolare è id, che è essa stessa un puntatore ad un oggetto, in modo non è necessario il *: un po 'complicato

id obj; 

:

NSInteger int; 
NSNumber *number; 

NSInteger è l'appropriata specifico per la piattaforma int ty pe, mentre NSNumber è un oggetto che può contenere un int, float o cosa hai.

+2

Grazie per la risposta. Questo mi fa chiedere ora, come vengono eliminati i tipi C dalla memoria? È fatto sotto la cappa dell'Obiettivo-C? – Meroon

+1

Le variabili di istanza dell'oggetto sono tutte contenute nella memoria dell'oggetto. Scompariranno tutti quando la memoria dell'oggetto verrà liberata. La differenza con le variabili di tipo oggetto è che sono puntatori, il che significa che la variabile stessa punta solo a un punto in memoria. Anche se la variabile del puntatore scompare, la memoria a cui punta è ancora assegnata. – Chuck

+2

Non dimenticare che a volte nei file di intestazione, Apple ha impostato typedef per le strutture in cui si fa sempre riferimento a esse con un puntatore. In tal caso il nome termina in "Rif". per esempio. CGImageRef che è un typedef di CGImage *. Quando vedi che non metti il ​​tuo * sul nome della variabile. – U62

5

I puntatori sono utilizzati per contenere l'indirizzo della memoria allocata. Quando crei un oggetto nel cacao, assegni la memoria e memorizzi l'indirizzo nel puntatore.

BOOL, char, int memorizza il valore.

Quando si crea una classe del alloc alloca la memoria per cui è necessario memorizzare un puntatore a che la memoria di essere in grado di accedervi:

NSMutableArray * arr = [[NSMutableArray alloc] init]; 

Come i tipi C vengono pulite dalla memoria?

I tipi "semplici" sono allocati nello stack. Quando un metodo viene chiamato, uno spazio viene allocato sullo stack per contenere tutte le variabili del metodo (più alcune altre cose come parametri e indirizzo di ritorno e così via). Quindi lo stack cresce. Una volta che il metodo restituisce lo stack si restringe e lo spazio utilizzato dal metodo è ora recuperato, quindi sì i tipi semplici verranno "ripuliti".

In realtà è molto più semplice di quanto sembri. Dai uno sguardo allo wikipedia Stack entry - section Hardware stacks per maggiori dettagli per soddisfare la tua curiosità.

Quando si "alloca memoria", la memoria viene allocata nell'heap. Heap è lì per l'intera esecuzione della tua applicazione. Una volta allocata memoria su un heap, si ottiene un indirizzo in quella memoria: questo indirizzo viene memorizzato nei puntatori. Il puntatore è solo una variabile che memorizza l'indirizzo di memoria.

Quando il tuo metodo ritorna, non hai più accesso alle tue "semplici" variabili dichiarate nel metodo (ad esempio BOOL, int, char e così via) ma la memoria su heap è ancora lì. Se hai ancora l'indirizzo della memoria (ad esempio il puntatore) puoi accedervi.

E le variabili di istanza del tipo "semplice" (modifica: all'interno dell'oggetto?)?

Quando si crea oggetto (stiamo parlando dell'obiettivo C e di Cocoa qui) e lo si assegna, si alloca lo spazio per l'intero oggetto.La dimensione dell'oggetto è la dimensione di tutte le sue variabili (non sono sicuro se obj-c aggiunge altre cose). Quindi le variabili di istanza fanno parte della memoria dell'oggetto su heap. Quando si rilascia/cancella l'oggetto, la sua memoria viene recuperata e non si ha più accesso alle variabili memorizzate nell'oggetto (in obj-c si chiama release, ogni oggetto conserva il conteggio dei riferimenti, quando il conteggio dei riferimenti raggiunge 0 l'oggetto viene deallocato - il la memoria su heap è reclamata).

+0

Oh ok che maschera senso per le variabili locali nell'ambito del metodo. Ma per quanto riguarda le variabili di istanza che sono tipi 'semplici'? – Meroon

1

Ogni classe Objective-C, come NSString, NSObject, NSView, ecc deve essere un puntatore, ad eccezione di alcuni tipi speciali come NSUInteger, che è solo un typedef per int credo.

NSString *stringyString = @"THIS STRING IS STRINGY!!!11"; 
NSOpenPanel *openPanel; 
NSObject *objectyObject; 
NSUInteger integeryInteger = 7; 

L'unica cosa che non lo è, perché è un puntatore a qualsiasi oggetto.

id pointerThatCanBeSetToAnyObject = [NSString stringWithString:@"HEYYYY"]; 

Solo C tipi di variabili come int, float, BOOL, ecc non richiedono un puntatore, eccetto stringhe C come array di caratteri.

int SEVEN = 7; 
float SIXPOINTTWO = 6.2; 
char *characterArray = "HEYYYYY"; 

Infine, le classi CoreFoundation hanno una sorta di ibrido; molte classi saranno puntatori, ma per alcune classi, come CFString, CFStringRef sarà già un puntatore. Molte funzioni CFString restituiscono CFStringRef. CFString * e CFStringRef sono intercambiabili con NSString * (questo è chiamato bridge senza pedaggio), anche se il compilatore probabilmente lo apprezzerà se lo lanci prima.

CFString *veryStringyString = @"STRINGYNESS!!11!one"; 
CFStringRef especiallyStringyString = @"STRRRRRRINNNNNGGGGYYYYY"; 
NSString *STRINGYNESS = (NSString *)veryStringyString; 
Problemi correlati