NSUInteger vs NSInteger,int vs unsigned,以及类似的情况

任何人都有专业知识来解释何时使用NSUInteger以及何时使用NSInteger?

我已经看到Cocoa方法返回NSInteger,即使在返回值始终是无符号的情况下也是如此。

根本原因是什么? 如果我们想要表示负值,NSInteger或int是否严格限制?

从NSObjCRuntime.h:

#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 

在处理NSUInteger与NSInteger时,您还应该了解整数转换规则:

例如,以下片段返回0(false),尽管您希望它打印1(true):

 NSInteger si = -1; NSUInteger ui = 1; printf("%d\n", si < ui); 

原因是[si]变量被隐式转换为unsigned int!

请参阅CERT的安全编码站点 ,以深入讨论这些“问题”以及如何解决这些问题。

默认情况下,假定整数已签名。 换句话说,编译器假定将调用整数变量来存储负数或正数。 这限制了范围可以在任一方向上达到的程度。 例如,32位int的范围为4,294,967,295。 在实践中,因为该值可以是正的或负的,所以范围实际上是-2,147,483,648到+2,147,483,647。 如果我们知道变量永远不会被调用来存储负值,我们可以将其声明为无符号,从而将(正)范围扩展为0到+4,294,967,295。 所以我想说,当你知道你的输出范围有限时,可以使用NSInteger。 我个人使用NSUInteger,如果我需要返回真正大的正面数字

如果您的方法具有适当限制的输出范围,您也可以使用NSInteger因为它更容易键入。 如你所说,如果你需要返回负数, NSInteger是镇上唯一的游戏; 如果我因某些原因需要返回真正的大数字,我只会使用NSUInteger

我不是特别了解cocoa,但通常签名整数的唯一缺点是它们通常有一半的最大值作为unsigned int。 比如大约20亿而不是40亿的32位系统。 一般来说这并不是一个很大的区别,因为如果你处理接近20亿的价值,你可能会同样担心同样情况下最多40亿,因为它仍然非常接近溢出乘以2或3。

有符号整数通常是首选,因为额外的灵活性和有条件的整数可以在几乎所有场景中使用的事实,无符号整数可以加上所有其他情况,它不能在需要负数的情况下使用。

如果要强制执行仅正值,则可能首选无符号。