2009-07-09 19 views
53

Acabo de empezar a aprender Objective-C, procedente de un fondo .Net y C# .Net de VB. Entiendo el uso del puntero, pero en los ejemplos de Objective-C veo el asterisco colocado en varios lugares diferentes, y si busco como sea posible, no he podido encontrar una respuesta sobre por qué. Cada búsqueda que intento presenta todo tipo de explicaciones sobre punteros (que realmente no necesito), pero ni una sola mención de los motivos/efectos de las diferentes ubicaciones del asterisco. Estos son algunos ejemplos que he visto:Colocación del asterisco en Objective-C

NSString *string; 
NSString * string; 
(NSString *) string; 
NSString* string; 

¿Qué significan estas diferentes posiciones del asterisco? Estoy seguro de que es una respuesta simple, pero es frustrante no poder encontrarla en ningún tutorial de Apple ni en la documentación de referencia, ni en línea hasta el momento.

¿Puede alguien por favor terminar con mi miseria y responder a esta pregunta desconcertante? ¡Gracias!

+1

@ john_5101 Si coloca cuatro espacios antes de su texto tipo código, lo tratará como código y lo hará parecer correcto (creo que esa es la respuesta al problema que eludió en su pregunta). –

+0

¿Podemos tomar esto como una oportunidad para declarar al azar uno de ellos de la manera "correcta" y detener esta tontería? – twiz

Respuesta

3

en realidad, todo es equivalente: un puntero a un nsstring !!

19

No hay diferencia, es una cuestión de estilo. Todos declaran una variable llamada string que es un puntero a un NSString. Los paréntesis son necesarios en algunos contextos (en particular las declaraciones de métodos) para aclarar que se trata de una declaración de tipo.

+0

Creo que quiere decir que no hay diferencia en el espaciado alrededor del asterisco, pero como otros han señalado, la 3ª línea es (por sí mismo) un elenco en un NSString * (que se podría usar si string es un 'id' de CFStringRef) o posiblemente parte de una declaración de método Objective-C. Para mí, al menos, su significado era claro. –

+4

I however prefiera la última forma (proveniente de un fondo C++): demarca claramente el tipo y el objeto. Aquí hay una pequeña y agradable discusión sobre este tema por parte de Stroustrup: http://www.research.att.com/~bs/bs_faq2. html # whitespace – PlagueHammer

23
1. NSString *string; 
2. NSString * string; 
3. (NSString *) string; 
4. NSString* string; 

1, 2 y 4 son exactamente idénticos. Todo es estilo Elija lo que quiera, o mezcle todo.

La opción # 3 tiene otro significado también, se usa en el casting. Por ejemplo:

t = (NSString *)string ; 

desechará string a un puntero NSString.

Pero la opción n. ° 3 es la sintaxis que probablemente usaría en un archivo .h o en la definición de la función en un archivo .m. Dentro de una función real, en el código que se "ejecuta" tiene un significado diferente.

+0

A pesar de que es un tipo válido de transmisión, nunca debería haber una necesidad de enviar explícitamente un objeto a NSString *; si está realizando downcasting desde id o void *, puede realizar el lanzamiento implícitamente, y si está actualizando de una subclase (como NSMutableString), también puede hacerlo implícitamente. –

+1

+1, pero el enunciado 3 es en realidad un "nop"; es probable que no desee utilizar esa línea en ningún lugar. Lo usarías como parte de una expresión para convertir la 'cadena 'en un NSString *, pero no es válido como una declaración. Por supuesto, no estoy familiarizado con Objective-C, así que si hay un uso para la declaración 3 en ese dialecto de C, por favor, hágamelo saber que estoy diciendo tonterías, y borraré este comentario. –

+0

De acuerdo. Y gracias, buen punto. Pero sintácticamente, es un elenco. Solo quería señalarlo porque definitivamente habrá momentos en que el póster de OP lo verá. – marcc

6

No importa dónde coloque el asterisco, todas las declaraciones crean punteros de tipo NSString.

Sin embargo, al usar múltiples nombres de variables en una línea, debe escribir el asterisco para cada variable.

NSString * nsstring, * nsstring2; 
+9

... que es una de las cosas más feas en C y, por lo tanto, debe evitarse. –

2

1, 2 y 4 son equivalentes y definen un puntero a un NSString. Mi preferencia personal es emular K & R tanto como sea posible, así que me gusta usar NSString *string;

(NString*)string; aunque una declaración válida, realmente no hace nada por sí misma.

$ cat foo.m 
#include <Cocoa/Cocoa.h> 

void foo() 
{ 
    NSString *string; 

    (NSString*) string; // doesn't do anything 
    42; // doesn't do anything either 
} 

$ gcc -Wall -c foo.m 
foo.m: In function 'foo': 
foo.m:7: warning: statement with no effect 
foo.m:8: warning: statement with no effect 
6
1. NSString *string; 
2. NSString * string; 
3. (NSString *) string; 
4. NSString* string; 

1,2 y 4 son equivalentes. El lenguaje C (y el superconjunto Objective-C de C) especifican una sintaxis que no es sensible al espacio en blanco. Por lo tanto, puede agregar libremente espacios donde elija como una cuestión de estilo. Toda la sintaxis relevante está delimitada por caracteres que no sean de espacios en blanco (por ejemplo, {, }, ;, etc.) [1].

3 es un tipo de conversión (indicando al compilador de C que utilice el tipo NSString* independientemente del tipo declarado de string).En Objective-C, el colado de instancias de objeto raramente es necesario. Puede usar el tipo id para las variables que pueden hacer referencia a instancias de cualquier tipo de objeto.

En las declaraciones de métodos, la sintaxis 3 (a veces sin el punto y coma final) se usa para declarar el tipo de parámetros del método. Un método de Objective-C puede tener este aspecto:

- (void)myMethodThatTakesAString:(NSString*)string; 

En esta declaración, el tipo del argumento con nombre string es de tipo NSString* (el principal - indica un método de instancia que se oponen a un método de clase). Una declaración de método con más de un parámetro podría tener este aspecto:

- (void)myMethodTakingAString:(NSString*)string andAnInteger:(NSInteger)intParam; 

[1] Esto se compara con lenguajes como Python que utilizan los espacios en blanco como un delimitador de bloque.

5

No hay ninguna diferencia, donde el * se coloca en una declaración de puntero es irrelevante.

3

No hay absolutamente ninguna diferencia entre estos.

+0

Hay una diferencia estilística que hace una gran diferencia desde la perspectiva de legibilidad del código. La respuesta de @me1974 es correcta ... debe ser como se muestra en apple – Ondrej

+0

Stylistic solamente, y la "legibilidad" es subjetiva. – coneybeare

+0

hacer una versión propia de un estilo recomendado no puede tener otro efecto sino disminuir la legibilidad para la mayoría de los desarrolladores ... – Ondrej

4

Sin diferencias, la colocación del espacio en blanco es irrelevante.

32

No hay diferencia, sin embargo, debe tener en cuenta que solo el primer "token" (por así decirlo) define el nombre del tipo, y * no es parte del nombre del tipo. Es decir:

NSString *aString, bString; 

Crea un puntero-a-NSString, y uno NSString. Para llegar a ser los dos punteros, realice una:

NSString *aString, *bString; 

o:

NSString *aString; 
NSString *bString; 
+0

Dado que la pregunta original era sobre la colocación de '*', edité su respuesta ligeramente para reducir la confusión. –

+2

... y, por supuesto, no puede declarar una variable NSString que no sea un puntero (fuera del dialecto POC), por lo que el primer ejemplo de código no se compilará. – Chuck

+2

¿'NSString * aString, bString' crearía 2 punteros a NSStrings? – micnguyen

4

No hay absolutamente ninguna diferencia. NSString * mystring y NSString * myString son idénticos.

3

el * funciona de la misma manera como lo hace en C estándar

esta es una buena introducción a poner el * en diferentes lugares y lo que hace: http://boredzo.org/pointers/

0

en el código de ejemplo la documentación xcode4 3. se puede ver todo el tiempo, por ejemplo en MoveMeView.m

#if 1 

- (void)growAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { 

#define MOVE_ANIMATION_DURATION_SECONDS 0.15 

[UIView beginAnimations:nil context:NULL]; 
[UIView setAnimationDuration:MOVE_ANIMATION_DURATION_SECONDS]; 
placardView.transform = CGAffineTransformMakeScale(1.1f, 1.1f); 
/* 
Move the placardView to under the touch. 
We passed the location wrapped in an NSValue as the context. 
Get the point from the value, then release the value because we retained it in touchesBegan:withEvent:. 
*/ 
NSValue *touchPointValue = (NSValue *)context; 
placardView.center = [touchPointValue CGPointValue]; 
[touchPointValue release]; 
[UIView commitAnimations]; 
} 
0

puede que no haya ninguna diferencia en las alternativas 1, 2 y 4 a la computadora, pero hay otros lectores del código.

Desde explicaciones como https://stackoverflow.com/a/1521382 y https://stackoverflow.com/a/16040884 y https://www.tutorialspoint.com/objective_c/objective_c_pointers.htm utilizan la primera alternativa:

1. NSString *string;

y todas las variables adicionales necesitan su propio asterisco, como en:

NSString *aString, *bString;

mi humilde sugerencia es que usamos la alternativa 1 como estándar.

Cuestiones relacionadas