Strange NSRangeException beyond bounds error in NSMutablearr



在我的应用程序中,我正在做音频分析。每一秒,我都在调用一些方法,比如这个:

- (NSNumber *) arrayAverage: (NSMutableArray *)array
{
    int countArray = [array count];
    if(!countArray)
        return nil;
    else if (countArray <= 5 )
        return [array valueForKeyPath:@"@avg.doubleValue"];
    else
    {
        // Création et initialisation d'un tableau temporaire
        NSMutableArray *averageArray = [[NSMutableArray alloc] initWithArray:array];
        NSSortDescriptor* desc = [[NSSortDescriptor alloc] initWithKey:@"self" ascending:YES];
        [averageArray sortUsingDescriptors:[NSArray arrayWithObject:desc]];

        for (int j = 0; j < countArray / 3; j++)
        {
            [averageArray removeLastObject];
            [averageArray removeObjectAtIndex:0];
        }

        NSNumber * average = [averageArray valueForKeyPath:@"@avg.doubleValue"];

        return average;
        }
}

问题是我有时会收到 NSRangeException 错误(1 分钟或几个小时后......这要看情况...说数组索引是越界的。奇怪的是,该索引并没有越界...这些方法仅在主线程上调用。提前感谢您的帮助!

编辑 1 :在 Anim 和 Abhinav 的帮助下,我更改了我的代码,如下所示。它已经工作了超过 2 小时 45 分钟(这是一个记录),然后崩溃并出现EXC_BAD_ACCESS代码 1 错误......

- (NSNumber *) arrayAverage: (NSMutableArray *)array
{
    NSArray *arrayCopy = [[NSArray alloc] initWithArray:array]; // CRASH with EXC_BAD_ACCESS error
    int countArray = [arrayCopy count];
    if(!countArray)
        return nil;
    else if (countArray <= 5 )
        return [arrayCopy valueForKeyPath:@"@avg.doubleValue"];
    else
    {
        // Création et initialisation d'un tableau temporaire
        NSMutableArray *averageArray = [[NSMutableArray alloc] initWithArray:arrayCopy];
        NSSortDescriptor* desc = [[NSSortDescriptor alloc] initWithKey:@"self" ascending:YES];
        [averageArray sortUsingDescriptors:[NSArray arrayWithObject:desc]];
        int startOfRange = countArray / 3;
        int rangeLength = countArray - 2 * (countArray / 3);
        NSArray* slicedArray = [averageArray subarrayWithRange:NSMakeRange(startOfRange, rangeLength)];
        NSNumber * average = [slicedArray valueForKeyPath:@"@avg.doubleValue"];
        return average;
    }
}

使用给定的代码段,它更多地会猜测这里发生了什么。请确保以下几点:

  1. 在调用"removeLastObject"或"removeObjectAtIndex"之前,检查数组计数是有意义的。仅当有要删除的内容时才调用它们。
  2. 鉴于 NSArray 和 NSMutableArray 不是线程安全的,请确保您正在操作的阵列没有同时被修改和使用。

我想在您的 For 循环中引入以下语句:

if (averageArray.count > 0) {
    [averageArray removeLastObject];
}
if (averageArray.count > 0) {
    [averageArray removeObjectAtIndex:0];
}

你可以再做一件事,只需在循环之前添加一个条件:这是片段,添加了注释:

- (NSNumber *) arrayAverage: (NSMutableArray *)array
{
    int countArray = [array count];
    if(!countArray)
        return nil;
    else if (countArray <= 5 )
        return [array valueForKeyPath:@"@avg.doubleValue"];
    else
    {
        // Création et initialisation d'un tableau temporaire
        NSMutableArray *averageArray = [[NSMutableArray alloc] initWithArray:array];
        NSSortDescriptor* desc = [[NSSortDescriptor alloc] initWithKey:@"self" ascending:YES];
        [averageArray sortUsingDescriptors:[NSArray arrayWithObject:desc]];
       if ([array count] > 0)  //Added one condition here---PR Singh
      { 
          for (int j = 0; j < countArray / 3; j++)
          {
             [averageArray removeLastObject];
             [averageArray removeObjectAtIndex:0];
          }
      }

        NSNumber * average = [averageArray valueForKeyPath:@"@avg.doubleValue"];

        return average;
        }
}

最新更新