Какая разница между NSNumber и NSInteger?

Какая разница между NSNumber и NSInteger? Есть ли такие примитивы, о которых я должен знать? Есть ли место для плавания?

Ответ 1

Существующие ответы полезны; добавив к ним:

Да, NSUInteger дает в два раза диапазон между положительными целыми числами как NSInteger, но я думаю, что еще одна критическая причина выбирать между ними - это просто различать случаи , где отрицательные значения просто не имеют смысла.

Пример: возвращаемое значение метода NSArray count является NSUInteger, что имеет смысл, поскольку мы не можем иметь массив с отрицательным числом элементов. Когда кодер знает его без знака, он имеет больше свободы для выполнения операций, которые могут быть ненадежными в подписанном случае, включая побитовые операции, такие как сдвиг. Этот пост в блоге рассказывает больше о подписанных vs unsigned.

Мое предположение о CGFloat vs NSFloat (которого не существует): Возможно, разработчикам элементов кода, названных NeXTStep, просто не нужно было указывать слишком много значений поплавка, вне временных интервалов. Таким образом, они дали NSTimeInterval, который является типом с плавающей точкой, но это явно предназначено для использования с временными интервалами. И, честно говоря, здорово иметь этот тип, потому что вы знаете, что это всегда означало быть в секундах без необходимости иметь дело со структурой. Когда вы переходите в мир графики (где живет Core Graphics), внезапно вокруг вас плавают, паря в воздухе (ха-ха). Поэтому имеет смысл представить там CGFloat. Этот абзац - все "просвещенные спекуляции".

Кроме того, просто чтобы быть понятным о , почему вы можете использовать NSInteger и т.д. вместо примитивных типов: так проще писать переносимый код, который в полной мере использует архитектуру машины. Например, CGFloat использует 32 бита на некоторых машинах и 64 бит на других, в основном в зависимости от того, насколько эффективный разрыв существует на этих машинах для этих размеров. В некоторых случаях нет реального ускорения для использования 32 бит против 64 бит, поэтому вы также можете использовать 64 бита. Если вы объявили что-то как CGFloat, вы внезапно получите эту дополнительную точность "бесплатно" при перекомпиляции.

И, как указал iKenndac, NSNumber является классом-оболочкой для всех этих (и других примитивных или квази-примитивных типов, таких как BOOL), что позволяет включать его в NSArray и NSDictionary s, с легкостью архивируйте их и выполняйте другие действия, которые может выполнять NSObject.

Ответ 2

NSNumber - это класс, а не примитив, и используется, когда вам нужно помещать необработанные числа в словари, массивы или иным образом инкапсулировать их. NSInteger, NSUInteger, CGFloat и т.д. являются простыми типами и соответствуют (на 32-битных системах, таких как iPhone) на int, unsigned int и float.

Как правило, если вам нужно где-то сохранить номер, используйте NSNumber. Если вы выполняете вычисления, циклы и т.д., Используйте NSInteger, NSUInteger или CGFloat.

Вы можете обернуть NSInteger в NSNumber:

NSNumber *aNumber = [NSNumber numberWithInteger:21];

... и верните его:

NSInteger anInteger = [aNumber integerValue];

Вы можете найти более подробную информацию здесь: http://iosdevelopertips.com/cocoa/nsnumber-and-nsinteger.html

Ответ 3

NSInteger похож на традиционный int на C. Это typedef. Существуют и другие, такие как NSUInteger, CGFloat и т.д., Что все являются синонимами для примитивных типов.

NSNumber полезен, когда вам нужно вставить число в NSArray или NSDictionary. Стандартная практика заключается в использовании этих коллекций по сравнению с вашим собственным; недостатком является то, что они могут содержать только объекты Objective-C.

NSNumber по существу обертывает int (или float и т.д.) в объект Obj-C (аналогично понятию С#/Java "бокс" примитивного типа), который может быть добавлен в массив:

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

По соображениям производительности, если можно, используйте примитивные типы (например, int, float, int []). Однако иногда вы не можете избежать NSArray/NSNumber, например, когда вы читаете или записываете записи в файл .plist.

Ответ 4

NSNumber обычно используется для хранения переменных, NSUInteger используется для арифметики

вы можете изменить NSNumber на NSUInteger, выполнив следующее:

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

Ранее было сказано, но как общее правило, переменные, которые должны быть определены с помощью *, являются объектными классами C, тогда как переменные, которые не нуждаются в *, являются примитивами C.

Ответ 5

Как уже было сказано другими, NSNumber является подклассом NSObject. Это не C-примитив (например, int, unsigned int, float, double и т.д.) NSInteger, CGFloat, NSUInteger просты typedefs над примитивами C.

Необходимость NSNumber возникает из-за необходимости использовать числа в качестве параметров для API, которым требуются объекты. Например, если вы хотите сохранить число в NSArray, в Core-Data или в NSDictionary.

Есть ли еще такие примитивы, о которых я должен знать? Ну, NSNumber не является примитивным типом, и он обертывает все виды чисел (поплавки, интегральные типы, булевы и т.д.). Вы также должны узнать о NSValue, который является базой для NSNumber.

Есть ли место для поплавков? Существует нет "NS" typedef для float, но NSNumber может обернуть вокруг любого числа с плавающей запятой:

NSNumber *myPi = [NSNumber numberWithFloat:3.1415926];

Или вы можете использовать примитивный тип CGFloat для CoreGraphics.