Domanda

Sto provando la mia mano al corso iPhone di Stanford su iTunes U e sono un po 'confuso riguardo ai puntatori. Nel primo incarico, ho provato a fare qualcosa del genere

NSString *processName = [[NSProcessInfo processInfo] processName];
NSInteger *processID = [[NSProcessInfo processInfo] processIdentifier];

Il che ha generato un errore, dopo averlo girato alla cieca, ho scoperto che era il * nella riga NSInteger a causare il problema.

Quindi ovviamente non capisco cosa sta succedendo. Spiegherò come penso che funzioni e forse qualcuno sarebbe abbastanza gentile da evidenziare il difetto.

  

A differenza dello sviluppo web, ora ho bisogno   preoccuparsi della memoria, beh, più che nello sviluppo web. Quindi quando io   creare una variabile, viene assegnato a   un po 'di memoria da qualche parte (RAM I   assumere). Invece di passare il   variabile intorno, passo un puntatore a   quel po 'di memoria in giro. E   i puntatori vengono dichiarati con il prefisso   nome della variabile con *.

Supponendo che abbia ragione, ciò che mi confonde è perché non devo farlo per NSInteger?

È stato utile?

Soluzione

NSInteger è un tipo primitivo, il che significa che può essere archiviato localmente nello stack . Non è necessario utilizzare un puntatore per accedervi, ma è possibile se si desidera. La linea:

NSInteger *processID = [[NSProcessInfo processInfo] processIdentifier];

restituisce una variabile effettiva, non il suo indirizzo. Per risolvere questo problema, devi rimuovere * :

NSInteger processID = [[NSProcessInfo processInfo] processIdentifier];

Puoi avere un puntatore a un NSInteger se ne vuoi davvero uno:

NSInteger *pointerToProcessID = &processID;

La e commerciale è l'indirizzo dell'operatore. Imposta il puntatore su NSInteger uguale all'indirizzo della variabile in memoria, anziché all'intero nella variabile.

Altri suggerimenti

Il motivo per cui non si dichiara NSInteger con un * è perché non è un oggetto. Un NSInteger è semplicemente un int o un long :

#if __LP64__
typedef long NSInteger;
#else
typedef int NSInteger;
endif

Se viene utilizzato in un'applicazione a 32 bit, è un numero intero a 32 bit e se viene creato in un'applicazione a 64 bit, è un numero intero a 64 bit.

Naturalmente, puoi passare un NSInteger come puntatore, ma la maggior parte delle funzioni accetta semplicemente argomenti come NSInteger e non un puntatore a esso.

Gli oggetti, d'altra parte, possono essere passati ad altre funzioni solo come puntatori. Questo perché gli oggetti hanno memoria allocata dinamicamente per loro, e quindi non possono essere dichiarati nello stack. Poiché un int o long ha una quantità fissa di memoria allocata per loro, questo non è un problema.

* significa "puntatore". La variabile oggetto contiene un puntatore a un oggetto, quindi ha un * ; la variabile NSInteger contiene un NSInteger, non un puntatore a un NSInteger, quindi non ha un * . Mettere * su quella variabile ti dà almeno un avvertimento perché stai mettendo un numero intero in una variabile puntatore.

NSInteger è solo un typedef per int, AFAIK.

Lavorare con i puntatori

NSInteger integer1 = 1;
NSLog(@"1. integer1:%ld &integer1:%p", integer1, &integer1);
//1. integer1:1 &integer1:0x7ffee59e8a98

NSInteger *integer2 = &integer1;
NSLog(@"2. integer2:%p &integer2:%p *integer2:%ld", integer2, &integer2, *integer2);
//2. integer2:0x7ffee59e8a98 &integer2:0x7ffee59e8a90 *integer2:1

*integer2 = 2;
NSLog(@"3. integer2:%p &integer2:%p *integer2:%ld \t integer1:%ld &integer1:%p", integer2, &integer2, *integer2, integer1, &integer1);
//3. integer2:0x7ffee59e8a98 &integer2:0x7ffee59e8a90 *integer2:2    integer1:2 &integer1:0x7ffee59e8a98
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top