77 votes

Quel NSNumber (Integer 16, 32, 64) dans Core Data dois-je utiliser pour garder NSUInteger

Je veux conserver NSUInteger dans mes données de base et je ne sais pas quel type je dois utiliser (integer 16, 32, 64) pour répondre à l'espace nécessaire.

D'après ce que j'ai compris :

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

et NSUInteger est le type def de unsigned long qui est égal à unsigned int ( Types en Objective-C sur iPhone )

Donc, si je convertis mon NSUInteger en NSNumber avec numberWithUnsignedInteger : et que je le sauvegarde sous NSNumber(Integer 32), je peux récupérer mes données en toute sécurité, n'est-ce pas ?

12voto

Daniel Eggert Points 4042

Est-ce que vous vraiment ont besoin de toute la gamme d'un NSUInteger ? Sur iOS, c'est une valeur non signée de 32 bits, qui peut devenir très grande. Elle sera transformée en une valeur signée de 64 bits.

Mais vous n'avez probablement pas besoin de tant de précision de toute façon. Le maximum pour un uint32_t est UINT32_MAX qui est de 4 294 967 295 (4 milliards). Si vous incrémentez une fois par seconde, il vous faudra plus de 136 ans pour atteindre cette valeur. L'iPhone de votre utilisateur ne sera plus là d'ici là... :)

34 votes

Cela ne répond pas vraiment à la question. Comment savez-vous quel type de données il stocke ? J'ai eu de nombreux cas où j'ai eu besoin de stocker un nombre bien plus grand que 4 milliards.

0 votes

Par exemple : var str2 = "small string with large hashValue" print(str2.hashValue) // 4799450061348893706

0 votes

Inutile - peut-être utilise-t-il un int comme moyen de stocker un état sur 32 attributs séparés - le 32 inverserait tous les bits et mettrait la pagaille dans les choses

8voto

ospr Points 1630

Dans la mesure du possible, lorsque vous écrivez des données sur un disque ou sur un réseau, il est préférable d'être explicite quant à la taille de la valeur. Au lieu d'utiliser NSUInteger comme type de données, utilisez uint16_t , uint32_t o uint64_t en fonction de la plage dont vous avez besoin. Cela se traduit naturellement par Integer 16, 32 et 64 dans Core Data.

Pour comprendre pourquoi, considérez le scénario suivant :

  1. Vous choisissez d'utiliser le type Integer 64 pour stocker votre valeur.
  2. Sur un appareil iOS 64 bits (par exemple l'iPhone 6), il enregistre la valeur 5 000 000 000.
  3. Sur un appareil iOS 32 bits, cette valeur est extraite du magasin dans un fichier de type NSUInteger (en utilisant la fonction unsignedIntegerValue ).

Maintenant, parce que NSUInteger n'est que de 32 bits sur le périphérique 32 bits, le nombre n'est plus 5 000 000 000 car il n'y a pas assez de bits pour représenter 5 milliards. Si vous aviez échangé le NUInteger à l'étape 3 pour uint64_t alors la valeur serait encore de 5 milliards.

Si vous devez absolument utiliser NSUInteger, vous devrez simplement vous méfier des problèmes décrits ci-dessus et coder de manière défensive.

En ce qui concerne le stockage de valeurs non signées dans les types de données de base apparemment signés, vous pouvez les stocker et les récupérer en toute sécurité :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X