2

辞書キーに基づいて配列を作成します。

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の容量で指定された配列にオブジェクトを挿入すると、オブジェクトがクラッシュするのはなぜですか?とても紛らわしい!

4

1 に答える 1

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];
        }
    }
}
于 2012-10-25T02:32:55.700 に答える