it-swarm.com.de

Welche NSNumber (Integer 16, 32, 64) in Core Data soll ich verwenden, um NSUInteger beizubehalten?

Ich möchte NSUInteger in meinen Kerndaten behalten und weiß nicht, welchen Typ ich verwenden soll (Ganzzahl 16, 32, 64), um den benötigten Speicherplatz zu berücksichtigen.

Meinem Verständnis nach:

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

und NSUInteger ist der Typ def von unsigned long, der gleich unsigned int ist ( Typ in Objective-C auf dem iPhone )

wenn ich also meine NSUInteger mit numberWithUnsignedInteger in NSNumber konvertiere und als NSNumber (Integer 32) speichere, könnte ich meine Daten sicher zurückholen, oder?

66
sarunw

Benötigen Sie wirklich den gesamten Bereich eines NSUInteger? Unter iOS ist das ein vorzeichenloser 32-Bit-Wert, der sehr groß werden kann. Es wird in einem 64-Bit mit Vorzeichen finden.

Aber wahrscheinlich brauchen Sie sowieso nicht so viel Präzision. Das Maximum für ein uint32_t ist UINT32_MAX das sind 4.294.967.295 (4 Milliarden). Wenn Sie einmal pro Sekunde inkrementieren, benötigen Sie mehr als 136 Jahre, um diesen Wert zu erreichen. Das iPhone Ihres Benutzers wird dann nicht mehr da sein ... :)

13
Daniel Eggert

Wenn möglich, sollten Sie beim Schreiben von Daten auf die Festplatte oder über ein Netzwerk die Größe des Werts genau angeben. Verwenden Sie anstelle von NSUInteger als Datentyp uint16_t, uint32_t Oder uint64_t, Je nachdem, welchen Bereich Sie benötigen. Dies übersetzt sich dann natürlich in Integer 16, 32 und 64 in Core Data.

Betrachten Sie dieses Szenario, um zu verstehen, warum:

  1. Sie können den Integer 64-Typ verwenden, um Ihren Wert zu speichern.
  2. Auf einem 64-Bit-iOS-Gerät (z. B. iPhone 6) wird der Wert 5.000.000.000 gespeichert.
  3. Auf einem 32-Bit-iOS-Gerät wird dieser Wert aus dem Speicher in ein NSUInteger abgerufen (unter Verwendung von NSNumber's unsignedIntegerValue).

Da NSUInteger auf dem 32-Bit-Gerät nur 32-Bit-Zeichen enthält, beträgt die Zahl nicht mehr 5.000.000.000, da nicht genügend Bits für 5 Milliarden Zeichen vorhanden sind. Wenn Sie in Schritt 3 NUInteger gegen uint64_t Getauscht hätten, wäre der Wert immer noch 5 Milliarden.

Wenn Sie unbedingt NSUInteger verwenden müssen, müssen Sie nur vorsichtig mit den oben beschriebenen Problemen sein und defensiv dafür codieren.

Soweit Sie vorzeichenlose Werte in den scheinbar signierten Core-Datentypen speichern, können Sie diese sicher speichern und abrufen:

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
8
ospr