Domanda

Quando dovrei usare NSInteger vs int durante lo sviluppo per iOS? Vedo nel codice di esempio di Apple usano NSInteger (o NSUInteger) quando passa un valore come argomento di una funzione o la restituzione di un valore da una funzione.

- (NSInteger)someFunc;...
- (void)someFuncWithInt:(NSInteger)value;...

Ma all'interno di una funzione che stanno solo usando int per monitorare un valore

for (int i; i < something; i++)
...

int something;
something += somethingElseThatsAnInt;
...

Ho letto (è stato detto) che NSInteger è un modo sicuro per fare riferimento a un intero sia in un ambiente a 64 bit o 32 bit quindi perché l'uso int a tutti?

È stato utile?

Soluzione

In genere è da utilizzare NSInteger quando non si sa che tipo di architettura del processore vostro codice potrebbe essere eseguito su, quindi si può per qualche motivo vuole il più grande tipo integer possibile, che su sistemi a 32 bit è solo un int, mentre su un sistema a 64 bit è una long.

mi piacerebbe restare con l'utilizzo di NSInteger invece di int / long meno che non li richiedono.

NSInteger / NSUInteger sono definiti come * typedef dinamica * s per uno di questi tipi, e sono definiti in questo modo:

#if __LP64__ || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif

Per quanto riguarda l'identificatore di formato corretto si dovrebbe usare per ciascuno di questi tipi, vedere la stringa Programmazione sezione di guida sulla piattaforma dipendenze

Altri suggerimenti

Perché usare int a tutti?

Apple utilizza int causa di una variabile di controllo del ciclo (che viene utilizzato solo per controllare le iterazioni del ciclo) int tipo di dati va bene, sia nel tipo di dati dimensioni e nei valori che può contenere per il vostro ciclo. Non c'è bisogno di piattaforma di tipo di dati dipende qui. Per una variabile di controllo del ciclo, anche a 16 bit int farà la maggior parte del tempo.

Apple utilizza NSInteger per un valore di ritorno della funzione o per un argomento di funzione perché in questo caso il tipo di dati [size] conta , perché quello che si sta facendo con una funzione sta comunicando / passaggio di dati con altri programmi o con altri pezzi di codice; vedere la risposta al Quando dovrei usare NSInteger vs int? nella tua domanda stessa ...

  

che [Apple] Uso NSInteger (o NSUInteger) quando si passa un valore come   argomento di una funzione di o restituire un valore da una funzione.

OS X è "LP64". Ciò significa che:

int è sempre di 32 bit.

long long è sempre di 64 bit.

NSInteger e long sono sempre puntatore dimensioni. Che significa che sono 32-bit su sistemi a 32 bit e 64 bit su sistemi a 64 bit.

Il motivo NSInteger esiste è perché molte API legacy utilizzati in modo non corretto int invece di long di tenere puntatore di dimensioni variabili, il che significava che le API hanno dovuto cambiare da int a long nelle loro versioni a 64 bit. In altre parole, un'API avrebbe firme diverse funzioni a seconda se si sta compilando per 32-bit o 64-bit architetture. NSInteger intende mascherare questo problema con queste API legacy.

il nuovo codice, l'uso int se avete bisogno di una variabile a 32 bit, long long se avete bisogno di un intero a 64 bit, e long o NSInteger se avete bisogno di una variabile puntatore dimensioni.

Se si scava nel implementazione di NSInteger:

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

Semplicemente, la NSInteger typedef fa un passo per voi: se l'architettura è a 32 bit, utilizza int, se è a 64 bit, utilizza long. Utilizzando NSInteger, non è necessario preoccuparsi di l'architettura che il programma è in esecuzione su.

Si dovrebbe usare NSIntegers se avete bisogno di confrontarli con i valori costanti, come NSNotFound o NSIntegerMax, in quanto questi valori saranno diversi nei sistemi a 32-bit e 64-bit, in modo da valori di indice, i conteggi e simili: uso NSInteger o NSUInteger .

Non fa male a utilizzare NSInteger nella maggior parte dei casi, eccetto che occupa il doppio della memoria. L'impatto della memoria è molto piccolo, ma se si dispone di una grande quantità di numeri che galleggiano intorno in qualsiasi momento, potrebbe fare la differenza per uso int.

Se si utilizza NSInteger o NSUInteger, si vuole di gettarli nella interi lunghe o interi unsigned long quando si utilizza stringhe di formato, come nuova funzione Xcode restituisce un avviso se si cerca di uscire un NSInteger come se fosse un noto lunghezza. Si dovrebbe allo stesso modo fare attenzione quando li invio a variabili o argomenti che vengono inseriti come interi, in quanto si rischia di perdere una certa precisione nel processo.

Nel complesso, se non ti aspetti di avere centinaia di migliaia di loro in memoria in una sola volta, è più facile da usare rispetto NSInteger costantemente preoccuparsi per la differenza tra i due.

Al momento (settembre 2014) Ti consiglio di utilizzare NSInteger/CGFloat quando si interagisce con iOS API ecc Se siete anche costruendo la tua app per arm64. Questo perché è probabile ottenere risultati imprevisti quando si utilizzano i tipi float, long e int.

Esempio: FLOAT / DOUBLE vs CGFLOAT

Come esempio prendiamo il metodo delegato UITableView tableView:heightForRowAtIndexPath:.

In un 32-bit applicazione solo che funzionerà bene se è scritto in questo modo:

-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 44;
}

float è un valore a 32 bit e il 44 si restituisce è un valore a 32 bit. Tuttavia, se si compila / eseguire questo stesso codice in un'architettura arm64 64 bit 44 sarà un valore a 64 bit. Restituendo un valore a 64 bit quando si attende un valore di 32 bit darà l'altezza di righe imprevisto.

È possibile risolvere questo problema utilizzando il tipo di CGFloat

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 44;
}

Questo tipo rappresenta un float 32 bit in un ambiente a 32 bit ed a 64 bit double in un ambiente a 64 bit. Pertanto quando si utilizza questo tipo di metodo riceverà sempre tipo previsto indipendentemente dall'ambiente di compilazione / runtime.

Lo stesso è vero per i metodi che si aspettano numeri interi. Tali metodi si aspettano un valore int 32 bit in un ambiente a 32 bit ed a 64 bit long in un ambiente a 64 bit. È possibile risolvere questo caso utilizzando il tipo di NSInteger che funge da int o un long basata sulla compilazione / runtime environemnt.

Su iOS, attualmente non importa se si utilizza int o NSInteger. Essa importa più se / quando iOS si sposta a 64-bit.

In poche parole, NSIntegers sono ints in codice a 32 bit (e quindi a 32 bit di lunghezza) e longs sul codice a 64 bit (longs in codice a 64 bit sono 64 bit di ampiezza, ma a 32 bit in 32 bit codice). La ragione più probabile per l'utilizzo di NSInteger invece di long è quello di non rompere il codice a 32 bit esistente (che utilizza ints).

CGFloat ha lo stesso problema: a 32 bit (almeno su OS X), è float; a 64 bit, è double.

Aggiornamento:. Con l'introduzione dei 5s iPhone, iPad Air, Mini iPad con Retina, e iOS 7, è ora possibile costruire codice a 64 bit su iOS

Aggiornamento 2:. Inoltre, utilizzando NSIntegers aiuta con il codice Swift interoperabilità

int = 4 byte (dimensione indipendentemente fissa del architetto) NSInteger = dipende dalla dimensione del architetto (ad es. Per 4 byte architetto = 4 byte dimensione NSInteger)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top