Pergunta

Eu estou tentando minha mão no campo de iPhone em Stanford no iTunes U e eu estou um pouco confuso sobre ponteiros. Na primeira tarefa, eu tentei fazer algo parecido com isto

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

O que gerou um erro, depois de tinkeing cegamente, eu descobri que ele era o * na linha NSInteger que estava causando o problema.

Então, eu obviamente não entendem o que está acontecendo. Vou explicar como eu acho que ele funciona e talvez alguém seria gentil o suficiente para apontar a falha.

Ao contrário de desenvolvimento web, agora eu preciso se preocupar com a memória, assim, mais do que no desenvolvimento web. Então, quando eu criar uma variável, ele é atribuído um pouco de um lugar de memória (RAM I presumir). Em vez de passar o em torno variável, que passam para um ponteiro aquele pedaço de volta memória. E ponteiros são declarados por prefixar o nome da variável com *.

Assumindo que estou certo, o que me intriga é por que eu não preciso fazer isso para NSInteger?

Foi útil?

Solução

NSInteger é um tipo primitivo, o que significa que podem ser armazenados localmente na pilha . Você não precisa usar um ponteiro para acessá-lo, mas você pode, se você quiser. A linha:

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

retorna uma variável real, não o seu endereço. Para corrigir isso, você precisa remover o *:

NSInteger processID = [[NSProcessInfo processInfo] processIdentifier];

Você pode ter um ponteiro para um NSInteger se você realmente quer um:

NSInteger *pointerToProcessID = &processID;

O e comercial é o endereço do operador. Ele define o ponteiro para o NSInteger igual ao endereço da variável na memória, em vez de para o número inteiro na variável.

Outras dicas

A razão que você não declarar NSInteger com um * é porque ele não é um objeto. Um NSInteger é simplesmente uma int ou um long:

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

Se estiver a ser utilizado numa aplicação de 32 bits, que é um número inteiro de 32-bit, e se ele está a ser construído em um aplicativo de 64 bits, que é um número inteiro de 64-bit.

Claro, você pode passar um NSInteger como um ponteiro, mas a maioria das funções simplesmente tomar argumentos como um NSInteger e não um ponteiro para ele.

Objetos, por outro lado, só pode ser passado para outras funções como ponteiros. Isso ocorre porque os objetos têm memória alocada dinamicamente para eles, e por isso não pode ser declarada na pilha. Uma vez que um int ou long tem uma quantidade fixa de memória alocada para eles, isso não é um problema.

Os meios * “ponteiro”. A variável de objecto mantém um apontador para um objecto, por isso, tem uma *; a variável NSInteger detém uma NSInteger, não um ponteiro para um NSInteger, por isso não tem uma *. Colocar o * sobre essa variável dá-lhe, pelo menos, um aviso porque você está colocando um inteiro em uma variável ponteiro.

NSInteger é apenas um typedef para int, AFAIK.

Trabalho com ponteiros

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top