Qual è la differenza tra NSNumber e NSInteger?
-
18-09-2019 - |
Domanda
Qual è la differenza tra NSNumber e NSInteger? Ci sono più primitive come questi che dovrei sapere? ce n'è una per i galleggianti?
Soluzione
Le risposte attuali sono utili; aggiungendo ad essi:
Sì, NSUInteger
dà il doppio della portata tra i numeri interi positivi come NSInteger
, ma penso che un altro motivo fondamentale per scegliere tra i due è semplicemente di distinguere tra i casi di dove i valori negativi semplicemente non hanno senso .
Esempio: il valore restituito metodo NSArray
di count
è un NSUInteger
, che ha senso poiché non possiamo avere una matrice con un numero negativo di elementi. Quando il codificatore sa che è senza segno, lui / lei ha più libertà di eseguire operazioni che potrebbero essere inaffidabili nel caso firmato, comprese le operazioni bit per bit come ad esempio lo spostamento. questo post del blog parla di più su firmata vs senza segno.
La mia ipotesi su CGFloat
vs NSFloat
(che non esiste): Potrebbe essere il caso che i progettisti degli elementi di codice NeXTStep-denominati semplicemente non avevano bisogno di specificare troppi valori float , al di fuori degli intervalli di tempo. Così hanno dato NSTimeInterval
, che è un tipo in virgola mobile, ma che è chiaramente indicata per l'uso con intervalli di tempo. E, francamente, è bello avere quel tipo, perché si sa è sempre destinata ad essere in pochi secondi senza avere a che fare con una struttura. Quando si sposta nel mondo della grafica (dove vive core grafico), galleggianti improvvisamente sono tutti intorno a te, librarsi in aria (haha). Quindi ha senso introdurre una CGFloat
lì. Questo paragrafo è tutto "speculazione educato".
Inoltre, tanto per essere chiari su per cui si potrebbe utilizzare NSInteger
etc invece di tipi primitivi : Perché in questo modo è più facile scrivere codice portatile che sfrutta appieno l'architettura della macchina. Ad esempio, un CGFloat
utilizza 32 bit su alcune macchine e 64 bit sugli altri, in funzione soprattutto quanto di un gap di efficienza c'è su quelle macchine per tali dimensioni. In alcuni casi, non c'è alcuna reale aumento di velocità per l'utilizzo di 32 bit vs 64 bit, così si potrebbe anche utilizzare 64 bit. Se hai dichiarato cose come CGFloat
di, improvvisamente ottenere che la precisione in più "gratis" quando si ricompila.
E, come iKenndac ha sottolineato, NSNumber
è una classe wrapper per tutti di questi (e altri tipi primitivi o quasi primitivi come il BOOL
) che consente di includere nel vostro NSArray
s e NSDictionary
s, archivio più facilmente, e fare altre cose che NSObject
s possono fare.
Altri suggerimenti
NSNumber
è una classe, non un primitivo, e viene utilizzato quando è necessario mettere i numeri grezzi in dizionari, gli array, o comunque li incapsulare. NSInteger
, NSUInteger
, CGFloat
, ecc sono tipi semplici e corrispondono (nei sistemi a 32-bt come l'iPhone) per int
, unsigned int
e float
.
Come regola generale, se avete bisogno di memorizzare un numero da qualche parte, utilizzare NSNumber
. Se stai facendo i calcoli, loop, ecc, l'uso NSInteger
, NSUInteger
o CGFloat
.
Puoi avvolgere un NSInteger
in un NSNumber
:
NSNumber *aNumber = [NSNumber numberWithInteger:21];
... e tornare indietro:
NSInteger anInteger = [aNumber integerValue];
È possibile trovare maggiori informazioni qui: http://iosdevelopertips.com/cocoa /nsnumber-and-nsinteger.html
NSInteger è proprio come un tradizionale int
in C. E 'un typedef. Ci sono altri come NSUInteger
, CGFloat
, ecc che tutti sono sinonimi di tipi primitivi.
NSNumber è utile quando è necessario attenersi un numero in un NSArray o NSDictionary. La pratica standard è di utilizzare queste raccolte contro posizionare il proprio; lo svantaggio è che possono contenere solo oggetti Objective-C.
NSNumber avvolge essenzialmente un int
(o float, ecc) in un oggetto Obj-C (simile al concetto di 'boxe' un tipo primitivo C # / Java) che può essere aggiunto ad un array:
NSArray * myArray = [[NSArray alloc] init];
[myArray addObject:3]; // invalid, will not compile.
[myArray [NSNumber numberWithInt:3]]; // ok
Per motivi di prestazioni, se è possibile, utilizzare i tipi primitivi (come int, float, int []). Tuttavia, a volte non si può evitare di NSArray / NSNumber, come ad esempio quando si sta leggendo o scrivendo le voci in un file .plist
.
NSNumber è generalmente utilizzato per memorizzare le variabili, NSUInteger viene utilizzato per aritmetica
è possibile modificare una NSNumber ad un NSUInteger in questo modo:
NSNumber *variable = @1;
NSUInteger variableInt = [variable unsignedIntegerValue];
E 'stato detto prima, ma come regola generale, le variabili che devono essere definiti con * sono classi Objective C, mentre le variabili che non hanno bisogno di un * sono C primitive.
Come detto da altri prima, NSNumber
è una sottoclasse NSObject
. Non è un C primitivo ( come int, unsigned int, float, double, ecc. ) NSInteger
, CGFloat
, NSUInteger
sono semplici typedefs
sopra le primitive C.
La necessità di NSNumber
nasce dalla necessità di usare numeri come parametri di API che richiedono oggetti. Esempio è, quando si desidera memorizzare un numero in un NSArray
, in core-dati, oppure in un NSDictionary
.
Ci sono più primitive come questi che dovrei sapere? Beh, NSNumber
non è un tipo primitivo, e si avvolge intorno a tutti i tipi di numeri (carri, tipi integrali, booleani e così via). Si dovrebbe anche conoscere NSValue, che è la base per NSNumber
.
ce n'è una per i galleggianti? Non v'è alcun typedef "NS" per galleggiare, ma NSNumber
può avvolgere intorno a qualsiasi numero di float:
NSNumber *myPi = [NSNumber numberWithFloat:3.1415926];
In alternativa è possibile utilizzare i CoreGraphics tipo primitivo CGFloat.