在Cocoa中,你更喜欢使用NSInteger还是int?为什么?

48

NSInteger/NSUInteger是Cocoa定义的替代普通内置类型的数据类型。

使用NS*类型是否有任何好处?你更喜欢哪一个,为什么?NSIntegerint在32位/64位平台上的宽度是否相同?

5个回答

58

据我理解,NSInteger等是相应C类型的安全版本。基本上它们的大小取决于架构,但是例如NSInteger 可以保证在当前架构下保存任何有效指针。

Apple建议您使用这些来处理OS X 10.5及更高版本,并且Apple的API将使用它们,因此养成使用它们的习惯绝对是一个好主意。它们需要输入更多内容,但除此之外似乎没有理由不使用它们。


这并不一定是情况 -- 请参阅我的回答“64位运行时的量化问题”。 - mmalc

43

64位运行时的量化问题

在某些情况下,使用标准类型而不是NSInteger可能有充分理由:64位系统中的“意外”内存膨胀。

显然,如果整数占用8个字节而不是4个字节,则值所占内存量增加了一倍。不过,鉴于并不是每个值都是整数,您通常不应期望应用程序的内存占用量翻倍。但是,Mac OS X分配内存的方式取决于请求的内存量。

目前,如果您请求512字节或更少的内存,malloc将向上舍入到16字节的下一个倍数。 但是,如果您请求超过512字节的内存,malloc将向上舍入到512的下一个倍数(至少1024字节)。假设您定义了一个类,其中包括五个NSInteger实例变量,而在32位系统上,每个实例占用272字节。在64位系统上,实例理论上需要544字节。但是,由于内存分配策略,每个实例实际上将占用1024字节(近四倍增加)。如果您使用大量这些对象,则应用程序的内存占用量可能比您预期的要大得多。如果将NSInteger变量替换为sint_32变量,则只使用512字节。

因此,在选择要使用的标量时,请确保选择合适的值。您是否需要比32位应用程序中所需的值更大?使用64位整数计算秒数不太可能是必要的...


2
是的,但从统计学上讲,让程序员远离位和字节更具生产力。我们正在谈论Cocoa,而不是libc。另一方面,在iPhone上,根据应用程序的情况,你可能有一点道理。 - IlDan
5
这里的问题不太清楚:我的评论直接涉及Cocoa以及选择代表变量类型时需要考虑的重要因素。仅仅因为你正在使用Cocoa并不意味着你永远不必考虑与应用程序性能相关的因素... - mmalc
9
现代设备的存储容量更加丰富并不是浪费内存的好借口。当然,偶尔浪费32位内存并不算什么,但如果这是一个结构体或实例变量,并且被分配了成千上万次,那么就会产生累计效应。粗心编程和无意中使用64位值而32位就足够会导致内存膨胀——如果你有机会避免这种情况,我想不到任何不去摘下显而易见的果实的好借口。 - Quinn Taylor

18

64位实际上是NSInteger和NSUInteger存在的原因;在10.5之前,它们不存在。这两个只是在64位中定义为long,在32位中定义为int:

#if __LP64__ || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif

因此,在需要“本机位”大小时,可以使用它们来代替更基本的C类型。 CocoaDev提供了更多信息。

链接已失效。 - Akshit Zaveri
看起来新的CocoaDev目前还没有那篇文章。 - Sören Kuklau
是的,它不行。将来请不要发布链接。如果可能,请在此处发布答案。仅发布链接违反了stackoverflow的答案指南。 - Akshit Zaveri

0

为了将数据导入和导出到文件或通过网络传输,我使用UInt32SInt64等类型...

这些类型保证在任何架构下都具有特定的大小,并有助于将代码移植到其他平台和语言中,这些平台和语言也共享这些类型。


0

我更喜欢标准的C语言声明方式,只是因为我经常在多种语言之间切换,这样我就不必过多考虑。但听起来我应该开始研究nsinteger了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接