2012-01-13 12 views
59

Voglio mantenere NSUInteger nei miei dati principali e non so quale tipo dovrei usare (intero 16, 32, 64) per soddisfare lo spazio necessario.What NSNumber (Integer 16, 32, 64) nei dati di base dovrei usare per mantenere NSUInteger

Dalla mia comprensione

Integer 16 can have minimum value of -32,768 to 32,767 
Integer 32 can have minimum value of -2,147,483,648 to 2,147,483,647 
Integer 64 can have minimum value of -very large to very large 

e NSUInteger è digitare DEF di lunga unsiged, che pari a unsigned int (Types in objective-c on iPhone)

quindi se posso convertire il mio NSUInteger a NSNumber con numberWithUnsignedInteger: e salvarlo come NSNumber (Numero intero 32) Potrei recuperare i miei dati in modo sicuro, giusto?

risposta

15

Sei davvero necessario l'intera gamma di un NSUInteger? Su iOS si tratta di un valore a 32 bit senza segno, che può diventare molto grande. Troverà in un 64 bit firmato.

Ma probabilmente non è necessaria la massima precisione. Il massimo per un UINT32_MAX è uint32_t che è 4.294.967.295 (4 miliardi). Se aumenti una volta al secondo, ti ci vorranno più di 136 anni per raggiungere quel valore. L'iPhone del tuo utente non sarà in giro da allora ... :)

+24

Questo in realtà non rispondere alla domanda. Come fai a sapere che tipo di dati sta memorizzando? Ho avuto molti casi in cui ho dovuto memorizzare un numero molto più grande di 4 miliardi. – Brandon

+0

Per esempio: 'var str2 = "piccola stringa con grandi hashValue"' ' di stampa (str2.hashValue)' ' // 4799450061348893706' –

+0

inutile - forse sta usando un int come un modo di memorizzare uno stato su 32 attributo separato - il 32 uno capovolgere tutti i bit e fare un casino di cose – SimonTheDiver

6

Se possibile, quando si scrivono dati su disco o su una rete, è meglio essere espliciti sulla dimensione del valore. Invece di utilizzare NSUInteger come tipo di dati, utilizzare uint16_t, uint32_t o uint64_t in base all'intervallo necessario. Questo quindi si traduce naturalmente in numero intero 16, 32 e 64 in Dati principali.

Per capire perché, si consideri questo scenario:

  1. si sceglie di utilizzare Integer 64 tipo per memorizzare il valore.
  2. Su un dispositivo iOS a 64 bit (ad es. IPhone 6) memorizza il valore 5.000.000.000.
  3. Su un dispositivo iOS a 32 bit, questo valore viene recuperato dallo store in un NSUInteger (utilizzando NSnumber's unsignedIntegerValue).

Ora perché NSUInteger è solo 32 bit sul dispositivo a 32 bit, il numero non è più 5.000.000.000 perché non ci sono abbastanza bit per rappresentare 5 miliardi. Se avevi scambiato lo NUInteger nel passaggio 3 per uint64_t, il valore sarebbe comunque 5 miliardi.

Se è assolutamente necessario utilizzare NSUInteger, sarà sufficiente essere cauti riguardo ai problemi descritti sopra e programmare il codice in modo difensivo.

Per quanto riguarda la memorizzazione di valori senza segno nelle tipologie Core Data apparentemente firmati, si può tranquillamente memorizzarli e recuperarli:

NSManagedObject *object = // create object 
object.valueNumber = @(4000000000); // Store 4 billion in an Integer 32 Core Data type 
[managedObjectContext save:NULL] // Save value to store 

// Later on 
NSManagedObject *object = // fetch object from store 
uint32_t value = object.valueNumber.unsignedIntegerValue; // value will be 4 billion 
Problemi correlati