В чем разница между NSNumber и NSInteger?
-
18-09-2019 - |
Вопрос
В чем разница между NSNumber и NSInteger?Есть ли еще подобные примитивы, о которых мне следует знать?Есть ли такой для поплавков?
Решение
Существующие ответы полезны;добавление к ним:
ДА, NSUInteger
дает удвоенный диапазон между целыми положительными числами в виде NSInteger
, но я думаю , что еще одна важная причина для выбора между этими двумя - это просто различать случаи где отрицательные значения просто не имеют смысла.
Пример: возвращаемое значение NSArray
's count
метод - это NSUInteger
, что имеет смысл, поскольку у нас не может быть массива с отрицательным числом элементов.Когда программист знает, что он без знака, у него / нее появляется больше свободы для выполнения операций, которые могут быть ненадежными в случае подписи, включая побитовые операции, такие как сдвиг. Это сообщение в блоге подробнее о подписанном и неподписанном.
Мое предположение о CGFloat
против NSFloat
(которого не существует):Возможно, разработчикам элементов кода с именем NeXTSTEP просто не нужно было указывать слишком много значений с плавающей запятой вне временных интервалов.Итак, они дали NSTimeInterval
, который является типом с плавающей запятой, но который явно предназначен для использования с временными интервалами.И, честно говоря, здорово иметь такой тип, потому что вы знаете, что он всегда создается за считанные секунды без необходимости иметь дело со структурой.Когда вы переходите в мир графики (где живет Core Graphics), внезапно вокруг вас появляются поплавки, парящие в воздухе (ха-ха).Таким образом, имеет смысл ввести CGFloat
там.Весь этот абзац - "обоснованное предположение".
Кроме того, просто для того, чтобы внести ясность в почему вы могли бы использовать NSInteger
и т.д. вместо примитивных типов:Потому что таким образом легче писать переносимый код, который в полной мере использует преимущества архитектуры компьютера.Например, a CGFloat
использует 32 бита на одних машинах и 64 бита на других, в значительной степени в зависимости от того, насколько велик разрыв в эффективности на этих машинах для данных размеров.В некоторых случаях нет реального ускорения при использовании 32 бит по сравнению с 64 битами, поэтому вы можете с таким же успехом использовать 64 бита.Если вы объявили вещи как CGFloat
таким образом, вы внезапно получаете эту дополнительную точность "бесплатно" при перекомпиляции.
И, как указал иКенндак,, NSNumber
является классом-оболочкой для всех из этих (и других примитивных или квазипримитивных типов, таких как BOOL
), что позволяет вам включить его в свой NSArray
ы и NSDictionary
s, проще архивировать их и выполнять другие действия, которые NSObject
s может сделать.
Другие советы
NSNumber
это класс, а не примитив, и используется, когда вам нужно поместить необработанные числа в словари, массивы или иным образом инкапсулировать их. NSInteger
, NSUInteger
, CGFloat
, etc являются простыми типами и соответствуют (в 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
NSInteger точно так же, как традиционный int
в C.Это typedef.Есть и другие, подобные NSUInteger
, CGFloat
, и т.д.все это синонимы для примитивных типов.
NSNumber полезен, когда вам нужно вставить число в NSArray или NSDictionary.Стандартная практика заключается в использовании этих коллекций вместо того, чтобы создавать свои собственные;недостатком является то, что они могут содержать только объекты Objective-C.
NSNumber по существу оборачивает int
(или float и т.д.) В объект Obj-C (аналогично концепции 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
файл.
NSNumber обычно используется для хранения переменных, NSUInteger используется для арифметики
вы можете изменить NSNumber на NSUInteger , выполнив это:
NSNumber *variable = @1;
NSUInteger variableInt = [variable unsignedIntegerValue];
Это было сказано ранее, но, как общее эмпирическое правило, переменные, которые должны быть определены с помощью *, являются классами Objective C, тогда как переменные, которые не нуждаются в *, являются примитивами C.
Как говорили другие ранее, NSNumber
является NSObject
подкласс.Это не примитив C (например, int, unsigned int, float, double и т.д.) NSInteger
, CGFloat
, NSUInteger
являются простыми typedefs
над примитивами языка Си.
Необходимость в NSNumber
возникает из-за необходимости использовать числа в качестве параметров для API, которым требуются объекты.Например, когда вы хотите сохранить число в NSArray
, В Core-Data, или в NSDictionary
.
Есть ли еще подобные примитивы, о которых мне следует знать?Что ж, NSNumber
это не примитивный тип, и он охватывает все виды чисел (с плавающей точкой, целочисленные типы, логические значения и так далее).Вам также следует узнать о NSValue, который является основой для NSNumber
.
Есть ли такой для поплавков?Для float нет typedef "NS", но NSNumber
может обернуться вокруг любого числа с плавающей запятой:
NSNumber *myPi = [NSNumber numberWithFloat:3.1415926];
Или вы могли бы использовать примитивный тип CoreGraphics CGFloat.