NSUserDefaults 的 "index 3 beyond bounds [0 .. 2]" 问题

Issue with "index 3 beyond bounds [0 .. 2]" with NSUserDefaults

我正在构建一个基本上可以跟踪体重的应用程序。为了更好的视觉效果,我附上截图:

屏幕截图的简短说明:我声明了一个 NSMutableArray,它将权重存储在索引 0,1,2,3(用黑色标记)中。 "initial" 栏与此 MutableArray 无关。每次添加权重时,它都会存储在 NSUserDefaults 中供以后使用。

想要实现的是:当MutableArray中的所有项目都被填充时,即显示所有条形图时,我想以索引0被删除的方式添加另一个权重,索引1和2 "placed/moved to the left" 增加 1 个位置,然后在索引 3 处添加新权重。

我的问题是:在填充所有柱后添加新权重时,出现此错误:

[__NSArrayM objectAtIndexedSubscript:]: index 3 beyond bounds [0 .. 2]

我知道这个错误意味着数组是空的,我只是不明白为什么。

这是初始化加载图表的 NSMutablearray 的代码:

if([weightUserDefaults objectForKey:@"weightMutableArray"] == nil){ // If no weight has ever been inserted then initialize array.

    // We initialize the array, otherwise it crashes. 
    [weightMutableArray addObject:@"0"];
    [weightMutableArray addObject:@"0"];
    [weightMutableArray addObject:@"0"];
    [weightMutableArray addObject:@"0"];

    // We store this 1st time array initialization in the UserDefaults
    [weightUserDefaults setValue:weightMutableArray forKey:@"weightMutableArray"];

    }else{ // If we have a weight from the Inaction, then show it in the graph

    weightMutableArray = [[weightUserDefaults objectForKey:@"weightMutableArray"] mutableCopy];;

    NSNumberFormatter *f = [[NSNumberFormatter alloc] init];

    PNBarChart * barChart = [[PNBarChart alloc] initWithFrame:CGRectMake(0, 0, optionsUIView.bounds.size.width, optionsUIView.bounds.size.height)];

      [barChart setYValues:@[
      [f numberFromString:[weightUserDefaults objectForKey:@"InitialWeight"]],
      [f numberFromString:[weightMutableArray objectAtIndex:0]],
      [f numberFromString:[weightMutableArray objectAtIndex:1]],
      [f numberFromString:[weightMutableArray objectAtIndex:2]],
      [f numberFromString:[weightMutableArray objectAtIndex:3]]]];

      [barChart strokeChart];
      [optionsUIView addSubview:barChart];
      [optionsUIView addSubview:addweightButton];

这是要添加新权重的IBAction。据我调查,我很确定问题出在这里。

for (int i=0;i < [weightMutableArray count]; i++){ // We start iterating in the array
  if(![weightMutableArray[3] isEqualToString:@"0"]){ // If index 3 is not 0, means its been filled
    [weightMutableArray removeObjectAtIndex:0]; // Then we remove the index 0

   for (int j = 1;j<=3;j++ )[weightMutableArray replaceObjectAtIndex:j-1 withObject:weightMutableArray[j]];
    [weightMutableArray insertObject:[[alertController textFields][0] text] atIndex:3]; // whatever its in index 1, put it in index 0. Then whatever its in index 2, put it in index 1, etc etc.

            break;
   }else if([weightMutableArray[i] isEqualToString:@"0"]){ //if any index is 0.

    [weightMutableArray replaceObjectAtIndex:i withObject:[[alertController textFields][0] text]]; // then fill data from the UITextfield.

            break;
        }
    }

    // After everything is done, just store it back in the UserDefaults.
    [weightUserDefaults setValue:weightMutableArray forKey:@"weightMutableArray"];

如果先删除第一项:

[weightMutableArray removeObjectAtIndex:0]; // Then we remove the index 0

数组在索引 0-2 中保留值 3。

删除前数组如下所示:

0: value1
1: value2
2: value3
3: value4

因为 (Cocoa) 数组总是封闭的(紧凑的),删除第一项会拉出以下元素。现在数组看起来像这样:

0: value2
1: value3
2: value4

因此没有索引为 3 的项目:

for (int j = 1;j<=3;j++ )

您根本不必将剩余的项目向上移动。已经完成了。

但是,恕我直言,您误解了可变集合和归零的整个概念。它是零为空反模式的特殊版本。