web-dev-qa-db-fra.com

Quelle est la différence entre NSNumber et NSInteger?

Quelle est la différence entre NSNumber et NSInteger? Y a-t-il plus de primitifs comme ceux-là que je devrais connaître? Y en a-t-il un pour les flotteurs?

61
mk12

Les réponses existantes sont utiles; en y ajoutant:

Oui, NSUInteger donne deux fois la plage parmi les entiers positifs comme NSInteger, mais je pense qu'une autre raison essentielle de choisir entre les deux est simplement de distinguer les cas où les valeurs négatives n'ont tout simplement pas de sens .

Exemple: la valeur de retour de la méthode NSArray de count est un NSUInteger, ce qui est logique car nous ne pouvons pas avoir un tableau avec un nombre négatif d'éléments. Lorsque le codeur sait qu'il n'est pas signé, il a plus de liberté pour effectuer des opérations qui pourraient ne pas être fiables dans le cas signé, y compris des opérations au niveau du bit comme le décalage. Ce billet de blog parle plus de signé vs non signé.

Ma conjecture sur CGFloat vs NSFloat (qui n'existe pas): Il se pourrait que les concepteurs des éléments de code nommés NeXTSTEP n'avaient tout simplement pas besoin de spécifier trop de valeurs flottantes, en dehors des intervalles de temps. Ils ont donc donné NSTimeInterval, qui est un type à virgule flottante, mais qui est clairement destiné à être utilisé avec des intervalles de temps. Et, franchement, c'est génial d'avoir ce type parce que vous savez qu'il est toujours censé être en quelques secondes sans avoir à traiter avec une structure. Lorsque vous entrez dans le monde graphique (où réside Core Graphics), des flotteurs sont soudainement autour de vous, planant dans l'air (haha). Il est donc logique d'y introduire un CGFloat. Ce paragraphe n'est qu'une "spéculation éclairée".

Aussi, juste pour être clair sur pourquoi vous pourriez utiliser NSInteger etc au lieu des types primitifs : Parce que de cette façon, il est plus facile d'écrire du code portable qui tire pleinement parti de l'architecture de la machine. Par exemple, un CGFloat utilise 32 bits sur certaines machines et 64 bits sur d'autres, en fonction en grande partie de l'écart d'efficacité qui existe sur ces machines pour ces tailles. Dans certains cas, il n'y a pas de véritable accélération pour utiliser 32 bits contre 64 bits, vous pouvez donc aussi bien utiliser 64 bits. Si vous avez déclaré des choses comme CGFloat, vous obtenez soudainement cette précision supplémentaire "gratuitement" lorsque vous recompilez.

Et, comme l'a souligné iKenndac, NSNumber est une classe wrapper pour tous ces derniers (et d'autres types primitifs ou quasi-primitifs comme BOOL) qui vous permet de l'inclure dans vos NSArrays et NSDictionarys, de les archiver plus facilement et de faire d'autres choses que NSObjects peut faire.

52
Tyler

NSNumber est une classe, pas une primitive, et est utilisé lorsque vous devez mettre des nombres bruts dans des dictionnaires, des tableaux ou les encapsuler autrement. NSInteger, NSUInteger, CGFloat, etc. sont des types simples et correspondent (sur les systèmes 32 bt comme l'iPhone) à int, unsigned int et float.

En règle générale, si vous devez stocker un numéro quelque part, utilisez NSNumber. Si vous faites des calculs, des boucles, etc., utilisez NSInteger, NSUInteger ou CGFloat.

Vous pouvez encapsuler un NSInteger dans un NSNumber:

NSNumber *aNumber = [NSNumber numberWithInteger:21];

... et récupérez-le:

NSInteger anInteger = [aNumber integerValue];

Vous pouvez trouver plus d'informations ici: http://iosdevelopertips.com/cocoa/nsnumber-and-nsinteger.html

59
iKenndac

NSInteger est comme un int traditionnel en C. C'est un typedef. Il y en a d'autres comme NSUInteger, CGFloat, etc. qui sont tous synonymes de types primitifs.

NSNumber est utile lorsque vous devez coller un nombre dans un NSArray ou NSDictionary. La pratique standard consiste à utiliser ces collections par opposition à la vôtre; l'inconvénient est qu'ils ne peuvent contenir que des objets Objective-C.

NSNumber encapsule essentiellement un int (ou flottant, etc.) dans un objet Obj-C (similaire au concept de C #/Java de "boxer" un type primitif) qui peut être ajouté à un tableau:

NSArray * myArray = [[NSArray alloc] init];
[myArray addObject:3]; // invalid, will not compile.
[myArray [NSNumber numberWithInt:3]]; // ok

Pour des raisons de performances, si vous le pouvez, utilisez des types primitifs (comme int, float, int []). Cependant, parfois, vous ne pouvez pas éviter NSArray/NSNumber, comme lorsque vous lisez ou écrivez des entrées dans un .plist fichier.

6
Jason

NSNumber est généralement utilisé pour stocker des variables, NSUInteger est utilisé pour l'arithmétique

vous pouvez changer un NSNumber en NSUInteger en procédant comme suit:

NSNumber *variable = @1;
NSUInteger variableInt = [variable unsignedIntegerValue];

Cela a déjà été dit, mais en règle générale, les variables qui doivent être définies avec * sont des classes Objective C, tandis que les variables qui n'ont pas besoin d'un * sont des primitives C.

2
eden

Comme d'autres l'ont déjà dit, NSNumber est une sous-classe NSObject. Ce n'est pas une primitive C (comme int, unsigned int, float, double, etc.) NSInteger, CGFloat, NSUInteger sont simples typedefs sur les primitives C.

La nécessité de NSNumber découle de la nécessité d'utiliser des nombres comme paramètres pour les API qui nécessitent des objets. Par exemple, lorsque vous souhaitez stocker un nombre dans un NSArray, dans Core-Data ou dans un NSDictionary.

Y a-t-il plus de primitifs comme ceux-là que je devrais connaître? Eh bien, NSNumber n'est pas un type primitif, et il enveloppe toutes sortes de nombres (flottants, types entiers, booléens, etc.). Vous devriez également vous renseigner sur NSValue, qui est la base de NSNumber.

Y en a-t-il un pour les flotteurs? Il n'y a pas de typedef "NS" pour float, mais NSNumber peut encapsuler n'importe quel nombre float:

NSNumber *myPi = [NSNumber numberWithFloat:3.1415926];

Ou vous pouvez utiliser le type primitif CoreGraphics CGFloat.

0
Motti Shneor