何时使用NSInteger与int

Shi*_*zam 338 types objective-c nsinteger ios

NSInteger为iOS开发时,我应该何时使用vs int?我在Apple示例代码中看到,当将值作为参数传递给函数或从函数返回值时,它们使用NSInteger(或NSUInteger).

- (NSInteger)someFunc;...
- (void)someFuncWithInt:(NSInteger)value;...
Run Code Online (Sandbox Code Playgroud)

但是在一个函数中,它们只是int用来跟踪一个值

for (int i; i < something; i++)
...

int something;
something += somethingElseThatsAnInt;
...
Run Code Online (Sandbox Code Playgroud)

我读过(被告知),其NSInteger是引用在任何一个64位或32位环境中,为什么使用一个整数一个安全的方式int呢?

Jac*_*kin 317

您通常希望在NSInteger不知道代码可能运行的处理器体系结构类型时使用,因此您可能出于某种原因需要最大可能 int类型,在32位系统上只需要一个long,而在64位系统上这是一个NSInteger.

我坚持使用int而不是long/ NSInteger除非你特别要求它们.

NSUInteger/ typedef被定义为*dynamic NSInteger*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
Run Code Online (Sandbox Code Playgroud)

关于每种类型应使用的正确格式说明符,请参阅" 字符串编程指南"中有关平台依赖性的部分.

  • 我不同意这个答案.我唯一会使用`NSInteger`来将值传递给指定它的API.除此之外,它没有优于int或long.至少用int或long你知道在printf或类似语句中使用什么格式说明符. (58认同)
  • 这是倒退.除非您有特殊原因,否则始终使用int.对简单整数使用特定于平台的定义只会使您的代码难以阅读. (13认同)
  • 另外,我想说除非你特别需要int或long int,否则最好使用NSInteger. (4认同)
  • @Shizam使用`int`可能更适合甚至是'long`.也许你知道它不会超过一定的范围,因此认为简单地使用`int`会更节省内存. (4认同)
  • 如果你需要存储一个长的并且在64b系统中使用NSInteger而其他用户使用32b系统会发生什么?您不会注意到失败,但用户会注意到. (3认同)
  • 啊是记忆,总是回到那个.好吧,我认为我现在有一个很好的决策矩阵,何时使用NSInteger vs int. (2认同)

Onl*_*You 44

为什么要使用int

Apple使用的int是因为循环控制变量(仅用于控制循环迭代)int数据类型很好,无论是数据类型大小还是它可以为循环保存的值.这里不需要平台相关的数据类型.对于循环控制变量,即使是16位int也会在大多数情况下完成.

Apple使用NSInteger函数返回值或函数参数,因为在这种情况下,数据类型[size]很重要,因为您正在使用函数正在与其他程序或其他代码进行通信/传递数据; 看到我应该何时使用NSInteger vs int的答案在你的问题本身......

当将值作为参数传递给函数从函数返回值时,它们[Apple]使用NSInteger(或NSUInteger).


Dar*_*ren 31

OS X是"LP64".这意味着:

int 总是32位.

long long 总是64位.

NSInteger并且long始终是指针大小的.这意味着它们在32位系统上是32位,在64位系统上是64位.

NSInteger的存在,究其原因是因为许多旧的API使用不当int,而不是long持有指针大小的变量,这意味着该API的必须从改变intlong其64位版本.换句话说,API将具有不同的功能签名,具体取决于您是否正在编译32位或64位体系结构. NSInteger打算用这些遗留API掩盖这个问题.

在新代码中,int如果需要32位变量,long long则需要使用,如果需要64位整数,long或者NSInteger需要指针大小的变量.

  • 历史是现实,但建议是可怕的.如果需要32位变量,请使用`int32_t`.如果需要64位整数,请使用`int64_t`.如果需要指针大小的变量,请使用`intptr_t`. (25认同)
  • 不,我建议如果你需要一个已知固定大小的整数类型,就不要使用它们.为此目的存在`<stdint.h>`类型. (7认同)
  • 斯蒂芬,你的建议是永远不要使用int,long或NSInteger吗? (5认同)
  • Stephen,我的回答是回答"何时使用NSInteger vs int"这个问题,而不是"什么是32位整数的跨平台类型名称".如果某人试图在NSInteger和int之间做出决定,他们也可能知道他们支持的平台有多大. (3认同)

Eva*_*ski 26

如果你深入研究NSInteger的实现:

#if __LP64__
typedef long NSInteger;
#else
typedef int NSInteger;
#endif
Run Code Online (Sandbox Code Playgroud)

简单地说,NSInteger typedef为您做了一个步骤:如果体系结构是32位,它使用int,如果它是64位,它使用long.使用NSInteger,您无需担心程序运行的体系结构.

  • 您需要担心,因为NSInteger的正确格式说明符取决于体系结构. (14认同)
  • 现在最简单的格式化方法就是装箱 - "NSLog("%@",@(1123));` (6认同)

Mad*_*ane 9

在iOS上,如果您使用int或,它目前无关紧要NSInteger.如果/当iOS移动到64位时,它会更重要.

简单地说,NSIntegers是int32位代码(因而是32位长),longs是64位代码(64位代码中的longs是64位宽,但32位代码中是32位).使用NSInteger而不是使用的最可能的原因long是不破坏现有的32位代码(使用ints).

CGFloat有同样的问题:在32位(至少在OS X上),它是float; 在64位上,它是double.

更新:随着iPhone 5s,iPad Air,带Miniina的iPad Mini和iOS 7的推出,您现在可以在iOS上构建64位代码.

更新2:此外,使用NSIntegers有助于Swift代码的互操作性.


Ash*_*Ash 9

如果需要将它们与常量值(如NSNotFound或NSIntegerMax)进行比较,则应使用NSIntegers,因为这些值在32位和64位系统上会有所不同,因此索引值,计数等:使用NSInteger或NSUInteger.

在大多数情况下使用NSInteger并没有什么坏处,除了它占用了两倍的内存.内存影响非常小,但是如果你在任何时候都有大量的数字浮动,那么使用整数可能会有所不同.

如果您使用NSInteger或NSUInteger,则在使用格式字符串时,您将希望将它们转换为长整数或无符号长整数,因为如果尝试注销NSInteger,就好像它具有已知长度一样,新的Xcode功能会返回警告.将它们发送到输入为int的变量或参数时,同样要小心,因为在这个过程中可能会失去一些精度.

总的来说,如果你不期望同时在内存中有数十万个,那么使用NSInteger比不断担心两者之间的差异更容易.


Leo*_*die 9

截至目前(2014年9月),NSInteger/CGFloat如果您还在为arm64构建应用程序,我建议在与iOS API等交互时使用.这是因为,当您使用可能会得到意想不到的效果float,longint类型.

示例:FLOAT/DOUBLE与CGFLOAT

作为示例,我们采用UITableView委托方法tableView:heightForRowAtIndexPath:.

在一个32位的应用程序中,如果它是这样编写的,它将正常工作:

-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 44;
}
Run Code Online (Sandbox Code Playgroud)

float是32位值,您返回的44是32位值.但是,如果我们在64位arm64架构中编译/运行同一段代码,那么44将是64位值.当预期32位值时返回64位值将产生意外的行高.

您可以使用CGFloat类型来解决此问题

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 44;
}
Run Code Online (Sandbox Code Playgroud)

此类型表示32 float位环境中的32位和64位环境double中的64位.因此,在使用此类型时,无论编译/运行时环境如何,该方法都将始终接收期望的类型.

对于期望整数的方法也是如此.这些方法预计32 int位环境中的32 位值和64位环境long中的64位值.您可以使用NSInteger作为intlong基于编译/运行时environemnt 的类型来解决此问题.