问题描述: 有一个方法, 传入两个NSInteger的参数, 用来检索一个二维数组(NSArray嵌套NSArray). 传入的参数可能是负的, 也可能大于数组长度, 所以做了安全限定: 假如是负的, 则反过来从数组尾向前检索(如数组长度是15, 参数是-2, 则取下标为13的元素); 假如大于数组长度, 则反过来从数组头向后检索(如数组长度是15, 参数是16, 则取下标为1的元素). 且受到调用函数的限制, 就算传递超限的值, 也不会传递(数组长度 * -1)以下, 或(数组长度 * 2)以上的值, 顶多[-5, 数组长度+5]的范围. 代码如下: - (PlaygroundBlock *)searchBlockWithCoordinate_X:(NSInteger)x Coordinate_Y:(NSInteger)y { if (y >= _blockArray.count){ y -= _blockArray.count; } else if (y < 0){ y += _blockArray.count; } NSArray *array = _blockArray[y]; if (x >= array.count){ x -= array.count; } else if (x < 0){ x += array.count; } PlaygroundBlock *block = array[x]; return block; } y是一维下标, 所以先通过y检索_blockArray; 再通过x检索当中对应的小数组. 本人碰到的问题是: y或x假如传递负数, 那么会执行(y >= _blockArray.count)或(x >= array.count)为真的语句块, 导致本来就是负数的y或x再减去数组长度, 结果显然会崩溃掉; 而假如传递大于数组长度的值, 也会执行以上条件为真的语句块, 结果倒是正确的; 传递数组下标范围以内的值, 结果也是正确的. 简而言之就是: x或y明明是负的, count明明是正的, 它就是判定x, y比count大... 问题排查: 1. 反复检查了_blockArray.count和array.count, 确定获取的数组长度是正确的; 2. 反复检查了形参x和y的值, 确定是在本人上述取值范围[-5, 数组长度+5]的范围内; 3. 反复打断点测试, 结果只要形参传递进来的时候是负数, 永远只走if为真的语句块, 永远不走else if语句块... 4. 不放心再看了看NSInteger的API文档, 确定这玩意就是long, 没有unsigned什么的... 有没有高手能帮本人看看问题到底出在哪了? 后续补充: 本人改了一下判断顺序, 先判断能否小于0, 再判断能否大于数组长度: - (PlaygroundBlock *)searchBlockWithCoordinate_X:(NSInteger)x Coordinate_Y:(NSInteger)y { if (y < 0){ y += _blockArray.count; } else if (y >= _blockArray.count){ y -= _blockArray.count; } NSArray *array = _blockArray[y]; if (x < 0){ x += array.count; } else if (x >= array.count){ x -= array.count; } PlaygroundBlock *block = array[x]; return block; } 结果当参数是负数时, 运行正确. 虽然问题修复了, 但本人的疑问还是没有解决: 第一段代码的写法为什么会导致明明y或x < count, 却判断y或x >= count为真?
解决方案
80
_blockArray.count 返回值类型为NSUInteger