2009-07-09 4 views
53

Ho appena iniziato a studiare Objective-C, proveniente da uno sfondo VB .Net e C# .Net. Comprendo l'uso del puntatore, ma negli esempi Objective-C vedo l'asterisco posto in diversi punti e, per quanto possa cercare, non sono stato in grado di trovare una risposta sul perché. Ogni ricerca che cerco fa emergere ogni genere di spiegazioni sui puntatori (di cui non ho davvero bisogno), ma non una singola menzione delle ragioni/effetti dei diversi posizionamenti dell'asterisco. Ecco alcuni esempi che ho visto:Posizionamento dell'asterisco in Objective-C

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

Che cosa significano queste diverse posizioni del asterisco significa? Sono sicuro che è una risposta semplice ma è frustrante non riuscire a trovarlo in nessuna delle esercitazioni e documentazione di riferimento di Apple o online finora.

Qualcuno può per favore finire la mia miseria e rispondere a questa domanda sconcertante? Grazie!

+1

@ john_5101 Se metti quattro spazi prima del tuo testo in codice, lo tratterà come codice e lo farà apparire corretto (credo che sia la risposta al problema a cui elimini nella tua domanda). –

+0

Possiamo considerarlo un'opportunità per dichiarare in modo casuale uno di questi modi "giusti" e fermare questa assurdità? – twiz

risposta

3

in realtà tutti equivalenti: un puntatore a un nsstring !!

19

Non c'è differenza: è una questione di stile. Tutti dichiarano una variabile denominata string che è un puntatore a una NSString. Le parentesi sono necessarie in alcuni contesti (in particolare le dichiarazioni dei metodi) per chiarire che si tratta di una dichiarazione di tipo.

+0

Penso che tu voglia dire che non c'è differenza nella spaziatura intorno all'asterisco, ma come altri hanno sottolineato, la terza linea è (da solo) un cast per un NSString * (che si potrebbe usare se la stringa è un 'id' di CFStringRef) o possibilmente parte di una dichiarazione del metodo Objective-C. Per me, almeno, il tuo significato era chiaro –

+4

preferisco l'ultima forma (proveniente da uno sfondo C++): delimita chiaramente il tipo e l'oggetto.Qui è una bella discussione su questo argomento di 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 e 4 sono esattamente identici. È tutto stile. Scegli quello che vuoi, o mescolare.

La scelta n. 3 ha anche un altro significato, è usata nel casting. Per esempio:

t = (NSString *)string ; 

sarà gettato string ad un puntatore NSString.

Ma la scelta n. 3 è la sintassi che probabilmente utilizzeresti in un file .h o nella definizione di funzione in un file .m. All'interno di una funzione reale, nel codice che è "eseguito" ha un significato diverso.

+0

Sebbene sia un typecast valido, non ci dovrebbe mai essere la necessità di trasmettere esplicitamente un oggetto a NSString * - se stai downcasting da id o void *, puoi eseguire il cast implicitamente e se stai eseguendo il upcasting da una sottoclasse (come NSMutableString), puoi anche farlo in modo implicito. –

+1

+1, ma l'affermazione 3 è in realtà un nop - probabilmente non vorrai usare quella linea ovunque. Lo useresti come parte di un'espressione per lanciare 'string' su un NSString *, ma non è valido come dichiarazione. Naturalmente, non ho familiarità con Objective-C, quindi se c'è un uso per la dichiarazione 3 in quel dialetto di C, per favore fatemi sapere che sto dando delle sciocchezze, e cancellerò questo commento. –

+0

concordato. E grazie, buon punto. Ma sintatticamente, è un cast. Volevo solo indicarlo perché sicuramente ci saranno momenti in cui il poster dell'OP lo vedrà. – marcc

6

non importa dove si inserisce l'asterisco, tutte le istruzioni creano puntatori di tipo NSString.

quando si utilizzano più nomi di variabili in una riga, è necessario scrivere l'asterisco per ciascuna variabile.

NSString * nsstring, * nsstring2; 
+9

... che è una delle cose più brutte in C e dovrebbe quindi essere evitato. –

2

1, 2 e 4 sono equivalenti e definiscono un puntatore a una NSString. La mia preferenza personale è quello di emulare K & R, per quanto possibile, quindi mi piace usare NSString *string;

(NString*)string; anche se una dichiarazione valida, in realtà non fare nulla da solo.

$ 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 e 4 sono equivalenti. Il linguaggio C (e il superset Objective-C di C) specificano una sintassi che è insensibile allo spazio bianco. Quindi puoi aggiungere liberamente spazi in cui scegli come questione di stile. Tutta la sintassi pertinente è delimitata da caratteri non di spaziatura (ad esempio {, }, ;, ecc.) [1].

3 è un tipo di trasmissione (che indica al compilatore C di utilizzare il tipo NSString* indipendentemente dal tipo dichiarato di string.In Objective-C, il casting di istanze di oggetti è raramente necessario. È possibile utilizzare il tipo id per le variabili che possono fare riferimento a istanze di qualsiasi tipo di oggetto.

Nelle dichiarazioni di metodo, la sintassi 3 (a volte senza il punto e virgola finale) viene utilizzata per dichiarare il tipo di parametri del metodo. Un metodo Objective-C può apparire come questo:

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

In questa dichiarazione, il tipo di argomento denominato string è scrivere NSString* (il principale - indica un metodo di istanza come opporsi ad un metodo di classe). Una dichiarazione di metodo con più di un parametro potrebbe essere simile a questo:

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

[1] Questo è rispetto a linguaggi come Python che utilizzano gli spazi bianchi come delimitatore blocco.

5

Non c'è alcuna differenza, in cui il * è inserito in una dichiarazione di puntatore è irrilevante.

3

Non c'è assolutamente alcuna differenza tra questi.

+0

C'è una differenza stilistica che fa molta differenza dal punto di vista della leggibilità del codice. La risposta di @ me1974 è corretta ... dovrebbe essere come mostrato dalla mela – Ondrej

+0

Solo stilistica, e la "leggibilità" è soggettiva. – coneybeare

+0

fare la propria versione di uno stile consigliato non può avere altro effetto ma diminuire la leggibilità per la maggior parte degli sviluppatori ... – Ondrej

4

Nessuna differenza, il posizionamento degli spazi bianchi è irrilevante.

32

Non c'è alcuna differenza, tuttavia è necessario tenere presente che solo il primo "token" (per così dire) definisce il nome del tipo e * non fa parte del nome del tipo. Vale a dire:

NSString *aString, bString; 

Crea un puntatore-to-NSString, e uno NSString. Per raggiungere entrambi da puntatori, effettuare una:

NSString *aString, *bString; 

o:

NSString *aString; 
NSString *bString; 
+0

Poiché la domanda iniziale riguardava il posizionamento di '*, ho modificato leggermente la risposta per ridurre la confusione. –

+2

... e ovviamente non è possibile dichiarare una variabile NSString che non sia un puntatore (al di fuori del dialetto POC), quindi il primo esempio di codice non verrà compilato. – Chuck

+2

'NSString * aString, bString' creerà 2 puntatori su NSStrings? – micnguyen

4

Non c'è assolutamente nessuna differenza. NSString * mystring e NSString * myString sono identici.

3

l'* funziona allo stesso modo come avviene in serie C.

Questa è una bella introduzione a mettere il * in luoghi diversi e che cosa fa: http://boredzo.org/pointers/

0

nel codice di esempio la documentazione xcode4 si può vedere 3. tutto il tempo, per esempio in 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

non ci può essere alcuna differenza nelle alternative 1, 2 e 4 al computer, ma ci sono gli altri lettori del codice.

Dal spiegazioni come https://stackoverflow.com/a/1521382 e https://stackoverflow.com/a/16040884 e https://www.tutorialspoint.com/objective_c/objective_c_pointers.htm utilizzano la prima alternativa:

1. NSString *string;

e tutte le variabili in più bisogno di loro asterisco come in:

NSString *aString, *bString;

mio modesto suggerimento è che usiamo l'alternativa 1 come standard.