为什么NSIndexPath排财产有符号整数?
它所能采取一个“有效”负值?
编辑
我还没有想过这个直到今天当我设置LLVM检查符号比较。 这使得编译器喷出出警告每当有indexPath.row <= [someArray count]
或类似。
为什么NSIndexPath排财产有符号整数?
它所能采取一个“有效”负值?
编辑
我还没有想过这个直到今天当我设置LLVM检查符号比较。 这使得编译器喷出出警告每当有indexPath.row <= [someArray count]
或类似。
这不是明智的做法是使用负值,如果你这样做,你会得到疯狂的结果
NSIndexPath* path = [NSIndexPath indexPathForRow:-2 inSection:0];
上述结果在0一节,和4294967294行(它看起来像一个的下溢NSUInteger
给我!)是安全知识,这只是附加的UIKit类别中发生的,而不是内NSIndexPath本身。 看着背后的概念NSIndexPath
,它确实没有意义的持有负值。 所以为什么?
核心对象NSIndexPath
从OS X使用NSUInteger
S代表了指数,但加入的UIKit使用NSInteger
。 该类别只有建立在核心对象的顶部,但使用的NSInteger
超过NSUInteger
不提供任何额外的功能。
为什么是这样工作的,我不知道。 我的猜测(我猜规定),是这是一个天真的API slipup第一iOS版推出的时候。 当UITableView
在IOS 2被释放,它用于NSInteger
S代表的各种东西(如numberOfSections
)。 想想看:这个概念是没有意义的,你不能有部分的负数。 现在,即使是在iOS 6中,它仍然使用NSInteger
,所以不打破与表视图以前的应用程序兼容性。
除了UITableView
,我们有补充NSIndexPath
,其在配合使用表视图,用于访问它的行和这样。 因为他们必须一起工作,他们需要兼容的类型(在这种情况下NSInteger
)。
要更改类型NSUInteger
全线将打破了很多东西,并为安全的API设计,一切都需要重命名,以便NSInteger的和NSUInteger同行可以通过侧安全工作的一面。 苹果可能不希望这种麻烦(也不做开发商!),因此他们有它保持NSInteger
。
一个可能的原因是无符号类型很容易溢。 作为一个例子,我有一个NSUInteger
用于笔划宽度可变在我的代码。 我需要创建一个“信封”周围涂上该行程,因此该代码点:
NSUInteger width = 3;
CGRect envelope = CGRectInset(CGRectZero, -width, -width);
NSLog(@"%@", NSStringFromCGRect(envelope));
一个无符号类型此输出{{inf, inf}, {0, 0}}
用带符号的整数你得到{{-3, -3}, {6, 6}}
其原因是,在之前的一元减号width
可变创建一个下溢。 这可能是显而易见的人物,但会惊讶很多程序员:
NSUInteger a = -1;
NSUInteger b = 1;
NSLog(@"a: %u, b: %u", a, -b); // a: 4294967295, b: 4294967295
因此,即使在它没有意义使用负值(笔划宽度不能为负数),这是有道理的负上下文中使用的值,导致下溢的情况。 切换到符号类型导致更少的惊喜,同时仍保持在合理的范围内高。 听起来像一个很好的平衡。
我认为UIKit的添置NSIndexPath
使用NSInteger
故意类型。 如果由于某种原因负行将作为传递parameter
给任何方法(我看没有的那一刻,虽然...),自动施放到NSIntegerMax + parameter
值将不会发生任何可能的对象也不会找一个大的离谱参数不存在。 不过,也有其他的方法来防止这种情况,所以它可能只是一个品味的问题。
我举个例子,不会采取NSUInteger
作为参数NSIndexPath
类,而是NSInteger
和检查的迹象,而且不会NSIndexPath
可言,如果任何参数为阴性。