2009-08-16 2 views

ответ

50

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

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

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

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

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

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

+0

На самом деле, очень некрасивая точка: NSTimeinterval - это двойной, а не поплавок. Я знаю, что double является коротким для плавающей запятой с двойной точностью, но все же. Кроме того, я понимаю, что компиляция CGFloat как двойная на 64-битном отлично, но NSInteger? Я не могу думать о ситуации, когда это было бы полезно. Скажите в коде, что вы делаете математику, которая требует 64 бит ... вы не можете использовать NSInteger, если вы скомпилируете 32. Если вы вписываетесь в 32, зачем использовать 64? Кажется странным. – iKenndac

+1

Вы правы, NSTimeInterval - это двойной. Я думаю, что он все еще считается «с плавающей точкой». Просто с двойной точностью. Я также согласен с тем, что во многих случаях много кода не улучшится, если NSInteger станет 64 бит. Но вот одна возможность: генератор случайных чисел. В этом случае вам действительно нужна скорость, поэтому вы можете использовать 32 бита, если это будет быстрее. Но если 64 бит работает так же хорошо, тогда вы внезапно получаете огромный импульс в случайном счастье (_much_ длиннее длину цикла и т. Д.) Без большой (если таковой) скорости. – Tyler

+0

Почему мы можем голосовать один раз? Brilliant! –

56

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

+0

Если число никогда не будет отрицательным, следует ли использовать NSUInteger? – mk12

+0

И что я должен использовать для числа с десятичной запятой? – mk12

+0

Почему это CGFloat, а не NSFloat? – mk12

5

NSInteger является как обычный int в C. Это typedef. Есть и другие, такие как NSUInteger, CGFloat и т. Д., Что все являются синонимами для примитивных типов.

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

NSNumber существу обертывания int (или поплавок, и т.д.) в объект 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.

+1

NSInteger, NSUInteger и CGFloat - это typedefs, которые безопасны под 32 или 64 бит. – Abizern

0

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

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

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

Есть ли место для поплавков? Там нет «NS» ЬурейеЕ для поплавка, но NSNumber можно обернуть вокруг любого числа с плавающей точкой:

NSNumber *myPi = [NSNumber numberWithFloat:3.1415926]; 

Или вы могли бы использовать CoreGraphics примитивный тип CGFloat.

2

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

вы можете изменить NSNumber к NSUInteger, делая это:

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

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

Смежные вопросы