Какая разница между 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.