insertObject:atIndex: - 索引3超出空数组的边界

时间:2012-10-25 02:22:53

标签: objective-c ios nsmutablearray nsarray nsdictionary

我根据字典键创建一个数组:

factsBuiltArray = [NSMutableArray arrayWithCapacity: 6];
if ([statusDict count] == 10) {
    for (NSString *key in [statusDict allKeys]) {
        if ([key isEqualToString: @"currenciesAndConversions"]) {
            [factsBuiltArray insertObject:key atIndex: 0];
        }
        else if ([key isEqualToString: @"languageAndTranslations"]) {
            [factsBuiltArray insertObject:key atIndex: 1];
        }
        else if ([key isEqualToString: @"plugSize"]) {
            [factsBuiltArray insertObject:key atIndex: 2];
        }
        else  if ([key isEqualToString: @"timezone"]) {
            [factsBuiltArray insertObject:key atIndex: 3]; // crashes over here
        }
        else if ([key isEqualToString: @"population"]) {
            [factsBuiltArray insertObject:key atIndex: 4];
        }
        else if ([key isEqualToString: @"wikipedia"]) {
            [factsBuiltArray insertObject:key atIndex: 5];
        }
    }
}

崩溃日志是:

*** -[__NSArrayM insertObject:atIndex:]: index 3 beyond bounds for empty array

为什么将对象插入到容量为6的数组中会使其崩溃?非常混乱!

1 个答案:

答案 0 :(得分:11)

容量只是容器类可容纳的对象数。在索引处插入要求索引是基于容器中包含的对象总数(而不是可以包含的对象总数)的新对象的有效放置。

如果您的数组值依赖于索引(看起来可能是不同的体系结构或数据结构会更好),那么您可以通过使用NSNull预填充数组来确保填充每个索引。这将要求您在稍后从数组中读取时检查NSNull虽然这可能是额外的工作,因此为什么这可能不是最好的方法。在任何情况下,您都可以将代码更改为以下内容以修复崩溃。

factsBuiltArray = [NSMutableArray arrayWithCapacity: 6];

for (NSUInter i = 0; i < 6; i++) {
    [factsBuiltArray addObject:[NSNull null]];
}

if ([statusDict count] == 10) {

    for (NSString *key in [statusDict allKeys]) {

        if ([key isEqualToString: @"currenciesAndConversions"]) {

            [factsBuiltArray replaceObjectAtIndex:0 withObject:key];
        }
        else if ([key isEqualToString: @"languageAndTranslations"]) {

            [factsBuiltArray replaceObjectAtIndex:1 withObject:key];
        }
        else if ([key isEqualToString: @"plugSize"]) {

            [factsBuiltArray replaceObjectAtIndex:2 withObject:key];
        }
        else  if ([key isEqualToString: @"timezone"]) {

        [factsBuiltArray replaceObjectAtIndex:3 withObject:key];

        }
        else if ([key isEqualToString: @"population"]) {

            [factsBuiltArray replaceObjectAtIndex:4 withObject:key];
        }
        else if ([key isEqualToString: @"wikipedia"]) {

            [factsBuiltArray replaceObjectAtIndex:5 withObject:key];
        }
    }
}