ios 何时使用 NSInteger 与 int
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4445173/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When to use NSInteger vs. int
提问by Shizam
When should I be using NSInteger
vs. int when developing for iOS? I see in the Apple sample code they use NSInteger
(or NSUInteger
) when passing a value as an argument to a function or returning a value from a function.
在NSInteger
为 iOS 开发时,我应该什么时候使用vs. int?我在 Apple 示例代码中看到他们在将值作为参数传递给函数或从函数返回值时使用NSInteger
(或NSUInteger
)。
- (NSInteger)someFunc;...
- (void)someFuncWithInt:(NSInteger)value;...
But within a function they're just using int
to track a value
但在一个函数中,他们只是int
用来跟踪一个值
for (int i; i < something; i++)
...
int something;
something += somethingElseThatsAnInt;
...
I've read (been told) that NSInteger
is a safe way to reference an integer in either a 64-bit or 32-bit environment so why use int
at all?
我读过(被告知)这NSInteger
是在 64 位或 32 位环境中引用整数的安全方法,那么为什么要使用int
呢?
采纳答案by Jacob Relkin
You usually want to use NSInteger
when you don't know what kind of processor architecture your code might run on, so you may for some reason want the largest possible integer type, which on 32 bit systems is just an int
, while on a 64-bit system it's a long
.
NSInteger
当您不知道您的代码可能在哪种处理器架构上运行时,您通常想使用它,因此您可能出于某种原因想要尽可能大的整数类型,在 32 位系统上它只是一个int
,而在 64 位系统上系统它是一个long
.
I'd stick with using NSInteger
instead of int
/long
unless you specifically require them.
我会坚持使用NSInteger
而不是int
/long
除非你特别需要它们。
NSInteger
/NSUInteger
are defined as *dynamic typedef
*s to one of these types, and they are defined like this:
NSInteger
/NSUInteger
被定义为typedef
这些类型之一的*dynamic *s,它们的定义如下:
#if __LP64__ || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
With regard to the correct format specifier you should use for each of these types, see the String Programming Guide's section on Platform Dependencies
关于您应该为这些类型中的每一种使用的正确格式说明符,请参阅字符串编程指南关于平台依赖性的部分
回答by Only You
Why use int
at all?
为什么要使用int
?
Apple uses int
because for a loop control variable (which is only used to control the loop iterations) int
datatype is fine, both in datatype size and in the values it can hold for your loop. No need for platform dependent datatype here.For a loop control variable even a 16-bit int
will do most of the time.
Apple 使用int
for 循环控制变量(仅用于控制循环迭代)int
数据类型很好,无论是数据类型大小还是它可以为循环保存的值。这里不需要平台相关的数据类型。对于循环控制变量int
,大多数情况下即使是 16 位也可以。
Apple uses NSInteger
for a function return value or for a function argument because in this case datatype [size] matters, because what you are doing with a function is communicating/passing data with other programs or with other pieces of code; see the answer to When should I be using NSInteger vs int?in your question itself...
Apple 使用NSInteger
函数返回值或函数参数,因为在这种情况下,数据类型 [size] 很重要,因为您对函数所做的是与其他程序或其他代码段通信/传递数据;请参阅何时应该使用 NSInteger 与 int的答案?在你的问题本身...
they [Apple] use NSInteger (or NSUInteger) when passing a valueas an argument to a function or returning a valuefrom a function.
他们 [Apple]在将值作为参数传递给函数或从函数返回值时使用 NSInteger(或 NSUInteger)。
回答by Darren
OS X is "LP64". This means that:
OS X 是“LP64”。这意味着:
int
is always 32-bits.
int
总是 32 位。
long long
is always 64-bits.
long long
总是 64 位。
NSInteger
and long
are always pointer-sized. That means they're 32-bits on 32-bit systems, and 64 bits on 64-bit systems.
NSInteger
并且long
总是指针大小。这意味着它们在 32 位系统上是 32 位,在 64 位系统上是 64 位。
The reason NSInteger exists is because many legacy APIs incorrectly used int
instead of long
to hold pointer-sized variables, which meant that the APIs had to change from int
to long
in their 64-bit versions. In other words, an API would have different function signatures depending on whether you're compiling for 32-bit or 64-bit architectures. NSInteger
intends to mask this problem with these legacy APIs.
NSInteger的存在,究其原因是因为许多旧的API使用不当int
,而不是long
持有指针大小的变量,这意味着该API的必须的变化,从int
到long
其64位版本。换句话说,根据您是为 32 位还是 64 位架构编译,API 将具有不同的函数签名。 NSInteger
打算用这些遗留 API 来掩盖这个问题。
In your new code, use int
if you need a 32-bit variable, long long
if you need a 64-bit integer, and long
or NSInteger
if you need a pointer-sized variable.
在您的新代码中,int
如果您需要一个 32 位变量,long long
如果您需要一个 64 位整数,long
或者NSInteger
如果您需要一个指针大小的变量,请使用。
回答by Evan Mulawski
If you dig into NSInteger's implementation:
如果你深入研究 NSInteger 的实现:
#if __LP64__
typedef long NSInteger;
#else
typedef int NSInteger;
#endif
Simply, the NSInteger typedef does a step for you: if the architecture is 32-bit, it uses int
, if it is 64-bit, it uses long
. Using NSInteger, you don't need to worry about the architecture that the program is running on.
简单地说,NSInteger typedef 为您做了一个步骤:如果架构是 32 位,它使用int
,如果它是 64 位,它使用long
. 使用 NSInteger,您无需担心程序运行的架构。
回答by MaddTheSane
On iOS, it currently does not matter if you use int
or NSInteger
. It will matter more if/when iOS moves to 64-bits.
在 iOS 上,目前使用int
或NSInteger
. 如果/何时 iOS 移动到 64 位,这将更重要。
Simply put, NSInteger
s are int
s in 32-bit code (and thus 32-bit long) and long
s on 64-bit code (long
s in 64-bit code are 64-bit wide, but 32-bit in 32-bit code). The most likely reason for using NSInteger
instead of long
is to not break existing 32-bit code (which uses int
s).
简单地说,NSInteger
s 是int
32 位代码中的s(因此是 32 位长),而long
s 是 64 位代码中的long
s(64 位代码中的 s 是 64 位宽,但 32 位代码中的 s 是 32 位)。使用NSInteger
而不是最可能的原因long
是不破坏现有的 32 位代码(使用int
s)。
CGFloat
has the same issue: on 32-bit (at least on OS X), it's float
; on 64-bit, it's double
.
CGFloat
有同样的问题:在 32 位(至少在 OS X 上),它是float
; 在 64 位上,它是double
.
Update:With the introduction of the iPhone 5s, iPad Air, iPad Mini with Retina, and iOS 7, you can now build 64-bit code on iOS.
更新:随着 iPhone 5s、iPad Air、配备 Retina 的 iPad Mini 和 iOS 7 的推出,您现在可以在 iOS 上构建 64 位代码。
Update 2:Also, using NSInteger
s helps with Swift code interoperability.
更新 2:此外,使用NSInteger
s 有助于 Swift 代码的互操作性。
回答by Ash
You should use NSIntegers if you need to compare them against constant values such as NSNotFound or NSIntegerMax, as these values will differ on 32-bit and 64-bit systems, so index values, counts and the like: use NSInteger or NSUInteger.
如果您需要将它们与 NSNotFound 或 NSIntegerMax 等常量值进行比较,您应该使用 NSIntegers,因为这些值在 32 位和 64 位系统上会有所不同,因此索引值、计数等:使用 NSInteger 或 NSUInteger。
It doesn't hurt to use NSInteger in most circumstances, excepting that it takes up twice as much memory. The memory impact is very small, but if you have a huge amount of numbers floating around at any one time, it might make a difference to use ints.
在大多数情况下使用 NSInteger 并没有什么坏处,只是它占用了两倍的内存。内存影响非常小,但如果您在任何时候都有大量数字浮动,使用整数可能会有所不同。
If you DO use NSInteger or NSUInteger, you will want to cast them into long integers or unsigned long integers when using format strings, as new Xcode feature returns a warning if you try and log out an NSInteger as if it had a known length. You should similarly be careful when sending them to variables or arguments that are typed as ints, since you may lose some precision in the process.
如果您确实使用 NSInteger 或 NSUInteger,则在使用格式字符串时,您将希望将它们转换为长整数或无符号长整数,因为如果您尝试注销 NSInteger,就好像它具有已知长度一样,新的 Xcode 功能会返回警告。同样,在将它们发送到类型为 int 的变量或参数时,您也应该小心,因为您可能会在此过程中失去一些精度。
On the whole, if you're not expecting to have hundreds of thousands of them in memory at once, it's easier to use NSInteger than constantly worry about the difference between the two.
总的来说,如果你不希望一次在内存中拥有数十万个,那么使用 NSInteger 比经常担心两者之间的差异更容易。
回答by Leon Lucardie
As of currently (September 2014) I would recommend using NSInteger/CGFloat
when interacting with iOS API's etc if you are also building your app for arm64.
This is because you will likely get unexpected results when you use the float
, long
and int
types.
截至目前(2014 年 9 月),NSInteger/CGFloat
如果您还在为 arm64 构建应用程序,我建议在与 iOS API 等交互时使用。这是因为当您使用float
,long
和int
类型时,您可能会得到意想不到的结果。
EXAMPLE: FLOAT/DOUBLE vs CGFLOAT
示例:FLOAT/DOUBLE 与 CGFLOAT
As an example we take the UITableView delegate method tableView:heightForRowAtIndexPath:
.
我们以 UITableView 委托方法为例tableView:heightForRowAtIndexPath:
。
In a 32-bit only application it will work fine if it is written like this:
在仅 32 位的应用程序中,如果它是这样编写的,它将正常工作:
-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 44;
}
float
is a 32-bit value and the 44 you are returning is a 32-bit value.
However, if we compile/run this same piece of code in a 64-bit arm64 architecture the 44 will be a 64-bit value. Returning a 64-bit value when a 32-bit value is expected will give an unexpected row height.
float
是一个 32 位值,您返回的 44 是一个 32 位值。但是,如果我们在 64 位 arm64 架构中编译/运行同一段代码,则 44 将是 64 位值。当需要 32 位值时返回 64 位值会产生意外的行高。
You can solve this issue by using the CGFloat
type
您可以使用CGFloat
类型解决此问题
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 44;
}
This type represents a 32-bit float
in a 32-bit environment and a 64-bit double
in a 64-bit environment. Therefore when using this type the method will always receive the expected type regardless of compile/runtime environment.
这种类型float
在 32 位环境中代表 32 位,double
在 64 位环境中代表 64 位。因此,在使用此类型时,无论编译/运行时环境如何,该方法将始终接收预期类型。
The same is true for methods that expect integers.
Such methods will expect a 32-bit int
value in a 32-bit environment and a 64-bit long
in a 64-bit environment. You can solve this case by using the type NSInteger
which serves as an int
or a long
based on the compile/runtime environemnt.
对于期望整数的方法也是如此。此类方法int
在 32 位环境中需要 32位值,long
在 64 位环境中需要 64 位值。您可以使用基于编译/运行时环境的类型NSInteger
作为 anint
或 a来解决这种情况long
。
回答by Ankit garg
int = 4 byte (fixed irrespective size of the architect) NSInteger = depend upon size of the architect(e.g. for 4 byte architect = 4 byte NSInteger size)
int = 4 字节(固定,与架构师的大小无关) NSInteger = 取决于架构师的大小(例如,对于 4 字节架构师 = 4 字节 NSInteger 大小)