OC编程碰到一个奇葩的问题, 百思不得其解, 求指点

iOS 码拜 7年前 (2017-05-04) 1399次浏览
问题描述:
有一个方法, 传入两个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

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明OC编程碰到一个奇葩的问题, 百思不得其解, 求指点
喜欢 (0)
[1034331897@qq.com]
分享 (0)