Pregunta

Estoy probando el curso de iPhone de Stanford en iTunes U y estoy un poco confundido acerca de los punteros. En la primera tarea, intenté hacer algo como esto

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

Lo que generó un error, después de jugar ciegamente, descubrí que era el * en la línea NSInteger el que causaba el problema.

Entonces obviamente no entiendo lo que está sucediendo. Explicaré cómo creo que funciona y tal vez alguien tenga la amabilidad de señalar la falla.

  

A diferencia del desarrollo web, ahora necesito   preocuparse por la memoria, bueno, más que en el desarrollo web. Entonces cuando yo   crear una variable, se le asigna un   poco de memoria en alguna parte (RAM I   asumir). En lugar de pasar el   variable alrededor, paso un puntero a   ese poco de memoria alrededor. Y   los punteros se declaran con el prefijo   nombre de variable con *.

Suponiendo que tengo razón, lo que me desconcierta es ¿por qué no necesito hacer eso para NSInteger?

¿Fue útil?

Solución

NSInteger es un tipo primitivo, lo que significa que se puede almacenar localmente en la pila . No necesita usar un puntero para acceder a él, pero puede hacerlo si lo desea. La línea:

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

devuelve una variable real, no su dirección. Para solucionar esto, debe eliminar el * :

NSInteger processID = [[NSProcessInfo processInfo] processIdentifier];

Puede tener un puntero a un NSInteger si realmente quiere uno:

NSInteger *pointerToProcessID = &processID;

El ampersand es la dirección del operador. Establece el puntero al NSInteger igual a la dirección de la variable en la memoria, en lugar de al entero en la variable.

Otros consejos

La razón por la que no declaras NSInteger con un * es porque no es un objeto. Un NSInteger es simplemente un int o un long :

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

Si se usa en una aplicación de 32 bits, es un número entero de 32 bits, y si se está creando en una aplicación de 64 bits, es un número entero de 64 bits.

Por supuesto, usted puede pasar un NSInteger como puntero, pero la mayoría de las funciones simplemente toman argumentos como NSInteger y no un puntero para eso.

Los objetos, por otro lado, solo se pueden pasar a otras funciones como punteros. Esto se debe a que los objetos tienen memoria asignada dinámicamente para ellos, por lo que no se pueden declarar en la pila. Dado que un int o long tiene una cantidad fija de memoria asignada para ellos, esto no es un problema.

El * significa & # 8220; puntero & # 8221 ;. La variable de objeto contiene un puntero a un objeto, por lo que tiene un * ; la variable NSInteger contiene un NSInteger, no un puntero a un NSInteger, por lo que no tiene un * . Poner el * en esa variable le da al menos una advertencia porque está poniendo un número entero en una variable de puntero.

NSInteger es solo un typedef para int, AFAIK.

Trabajar con punteros

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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top