Когда я должен использовать NSInteger
против INT при разработке для iOS? Я вижу в примере кода Apple, который они используют NSInteger
(или NSUInteger
), когда передают значение в качестве аргумента функции или возвращают значение из функции.
- (NSInteger)someFunc;...
- (void)someFuncWithInt:(NSInteger)value;...
Но внутри функции, которую они просто используют int
для отслеживания значения
for (int i; i < something; i++)
...
int something;
something += somethingElseThatsAnInt;
...
Я читал (мне сказали), что NSInteger
это безопасный способ ссылаться на целое число в 64-битной или 32-битной среде, так зачем int
вообще его использовать ?
источник
int
лучше подойдет даже дляlong
. Может быть, вы знаете, что он не превысит определенный диапазон, и поэтому думаете, что он будет более эффективным в использовании памятиint
.NSInteger
для передачи значений и из API, который его определяет. Кроме этого он не имеет никакого преимущества перед int или long. По крайней мере с int или long вы знаете, какие спецификаторы формата использовать в printf или аналогичном выражении.Зачем
int
вообще использовать ?Apple использует
int
потому, что для переменной управления циклом (которая используется только для управления итерациями цикла)int
тип данных хорош, как по размеру типа данных, так и по значениям, которые он может содержать для вашего цикла. Здесь не требуется тип данных, зависящий от платформы. Для переменной управления цикломint
большую часть времени будет выполнять даже 16-битная переменная .Apple использует
NSInteger
возвращаемое значение функции или аргумент функции, потому что в этом случае тип данных [размер] имеет значение , потому что то, что вы делаете с функцией, это передача / передача данных с другими программами или с другими частями кода; см. ответ на вопрос Когда я должен использовать NSInteger против INT? в самом вашем вопросе ...источник
OS X является "LP64". Это означает, что:
int
всегда 32-битныйlong long
всегда 64-битныйNSInteger
иlong
всегда размером с указатель. Это означает, что они 32-разрядные в 32-разрядных системах и 64-разрядные в 64-разрядных системах.Причина, по которой NSInteger существует, заключается в том, что многие устаревшие API неправильно используются
int
вместо того,long
чтобы хранить переменные размером с указатель, что означало, что API пришлось менять сint
наlong
64-битные версии. Другими словами, API будет иметь разные сигнатуры функций в зависимости от того, компилируете ли вы для 32-битной или 64-битной архитектуры.NSInteger
намерен замаскировать эту проблему с помощью этих устаревших API.В своем новом коде используйте,
int
если вам нужна 32-битная переменная,long long
если вам нужно 64-битное целое число,long
илиNSInteger
если вам нужна переменная размером с указатель.источник
int32_t
. Если вам нужно 64-битное целое число, используйтеint64_t
. Если вам нужна переменная размером с указатель, используйтеintptr_t
.<stdint.h>
типы существуют для этой цели.LP64
это не гарантирует, чтоlong long
это 64 бит.LP64
Платформа может избрать , чтобыlong long
быть 128 - битное целое.Если вы копаетесь в реализации NSInteger:
Проще говоря, typedef NSInteger делает шаг за вас: если архитектура 32-битная, она использует
int
, если она 64-битная, она используетlong
. Используя NSInteger, вам не нужно беспокоиться об архитектуре, на которой работает программа.источник
long long
. Таким образом, все числовые типы будут использовать один и тот же спецификатор типа.NSLog("%@", @(1123));
NSLog("%li", (long)theNSInteger);
Вы должны использовать NSIntegers, если вам нужно сравнить их с постоянными значениями, такими как NSNotFound или NSIntegerMax, так как эти значения будут отличаться в 32-разрядных и 64-разрядных системах, поэтому значения индекса, числа и т. П .: используйте NSInteger или NSUInteger.
Использование NSInteger в большинстве случаев не повредит, за исключением того, что он занимает вдвое больше памяти. Влияние на память очень мало, но если у вас есть огромное количество чисел, плавающих в одно время, это может иметь значение для использования целых чисел.
Если вы используете NSInteger или NSUInteger, при использовании строк форматирования вы захотите привести их к длинным целым или длинным целым без знака, так как новая функция Xcode возвращает предупреждение, если вы попытаетесь выйти из NSInteger так, как если бы он имел известную длину. Точно так же вы должны быть осторожны при отправке их переменным или аргументам, которые вводятся как целые, так как вы можете потерять некоторую точность в процессе.
В целом, если вы не ожидаете, что сотни тысяч их будут в памяти одновременно, проще использовать NSInteger, чем постоянно беспокоиться о разнице между ними.
источник
На данный момент (сентябрь 2014 г.) я бы рекомендовал использовать
NSInteger/CGFloat
при взаимодействии с iOS API и т. Д., Если вы также создаете свое приложение для arm64. Это потому , что вы, вероятно , получите неожиданные результаты при использованииfloat
,long
иint
типов.ПРИМЕР: FLOAT / DOUBLE против CGFLOAT
В качестве примера мы берем метод делегата UITableView
tableView:heightForRowAtIndexPath:
.В 32-битном приложении оно будет работать нормально, если оно написано так:
float
это 32-битное значение, а возвращаемое вами 44 - это 32-битное значение. Однако, если мы скомпилируем / запустим этот же кусок кода в 64-битной архитектуре arm64, 44 будет 64-битным значением. Возвращение 64-битного значения, когда ожидается 32-битное значение, даст неожиданную высоту строки.Вы можете решить эту проблему, используя
CGFloat
типЭтот тип представляет 32-разрядную
float
в 32-разрядной среде и 64-разряднуюdouble
в 64-разрядной среде. Поэтому при использовании этого типа метод всегда будет получать ожидаемый тип независимо от среды компиляции / среды выполнения.То же самое верно для методов, которые ожидают целые числа. Такие методы ожидают 32-битное
int
значение в 32-битной среде и 64-битноеlong
в 64-битной среде. Вы можете решить этот случай, используя тип,NSInteger
который служит какint
илиlong
основанный на environemnt времени компиляции / выполнения.источник
На iOS это в настоящее время не имеет значения, используете ли вы
int
илиNSInteger
. Это будет иметь большее значение, если / когда iOS перейдет на 64-битную версию.Проще говоря,
NSInteger
s - этоint
32-битный код (и, следовательно, 32-битный код), аlong
s - 64-битный код (long
s в 64-битном коде имеют ширину 64 бит, но 32-битный в 32-битном коде). Наиболее вероятная причина использованияNSInteger
вместо этогоlong
состоит в том, чтобы не нарушать существующий 32-битный код (который используетint
s).CGFloat
имеет ту же проблему: на 32-битной (по крайней мере на OS X), этоfloat
; на 64-битной, это такdouble
.Обновление: с появлением iPhone 5s, iPad Air, iPad Mini с Retina и iOS 7 теперь вы можете создавать 64-битный код на iOS.
Обновление 2: также использование
NSInteger
s помогает в совместимости кода Swift.источник
int = 4 байта (фиксированный независимо от размера архитектора) NSInteger = зависит от размера архитектора (например, для 4-байтового архитектора = 4 байта размера NSInteger)
источник