与NSUserDefaults

时间:2017-12-02 15:53:30

标签: ios objective-c nsmutablearray nsuserdefaults

我正在构建一个基本上跟踪重量的应用程序。为了更好的视觉方法,我附上了一个截图:

enter image description here

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

想要实现的是:当填充MutableArray中的所有项目时,即显示所有条形图时,我想以删除索引0的方式添加另一个权重,索引1和2被“放置/移动”向左“通过1位置,然后在索引3处添加新权重。

我的问题是:在填写所有栏后添加新的重量时,我收到此错误:

  

[__ NSArrayM objectAtIndexedSubscript:]:索引3超出界限[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"];

1 个答案:

答案 0 :(得分:0)

如果您先删除第一项:

[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++ )

您根本无需移动剩余的物品。它已经完成了。

但是,让我在所有方面说出这一点,你误解了可变集合和归零的整个概念。它是零的特殊版本,是null反模式。