int和NSInteger有什么区别?

14

2个回答

20

我们能够互换使用int和NSInteger吗?

不行。对于现代OS X Cocoa所使用的LP64架构,NSInteger是64位宽的。这意味着,如果您将NSInteger强制转换为int,与NSNotFound进行比较的操作可能会失败。以下是一个例子:

NSRange theRange = [@"foo" rangeOfString @"x"];
int location = theRange.location;
if (location == NSNotFound) // comparison is broken due to truncation in line above
{
    // x not in foo
}
在我看来,你只应在需要向Cocoa传递参数或从Cocoa接收结果且文档中指定数据类型为NSInteger的情况下使用它。在所有其他情况下:
  • 如果您不关心类型的宽度,请使用C类型,例如intlong
  • 如果您关心类型的宽度,请使用C99 stdint.h类型,例如int32_tint64_t
  • 如果您需要一个足够大以容纳指针的整数,请使用intptr_tuintptr_t

此外,如果您需要计算两个指针之间的差异,应使用 ptrdiff_t,而对于内存中对象的大小,则适用 size_t。对于磁盘上文件的偏移量,请使用 off_t。所有这些都是基本的 C 语言知识。 - al45tair

2

我建议使用标准的C99 uintptr_t作为指针大小的整数类型。NSInteger的定义似乎不够清晰,不能确定它保证能够存储一个指针。

如果必须使用API中使用的NSInteger,请使用它。但是,对于所有实际目的,long都可以胜任。

看着NSObjCRunTime,我真的无法理解其当前定义的动机。可能是为了有足够大的整数类型,例如能够达到NSArray中的最大项数?

#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

1
不要使用整型,而要使用uintptr_tintptr_t来表示指针大小的整数。 - al45tair
谢谢,我太C++-98了(而且在这种情况下是错误的)。回答已经调整。 - Steven Kramer

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