0

コンソールに出力されるエラーは次のとおりです。

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** 
-[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 1]'
*** First throw call stack:
(0x27f0012 0x1a51e7e 0x27a5b44 0xde6d 0xe2f8fb 0xe2f9cf 0xe181bb 0xe28b4b 0xdc52dd 0x1a656b0 0x97efc0 0x97333c 0x973150 0x8f10bc 0x8f2227 0x99c333 0x99c75f 0x27af376 0x27aee06 0x2796a82 0x2795f44 0x2795e1b 0x22677e3 0x2267668 0xd74ffc 0x258d 0x24b5 0x1)
libc++abi.dylib: terminate called throwing an exception

プログラムは正確に次の場所で中断します。

NSString *cellValue = [models objectAtIndex:indexPath.row];

cellForRowAtIndexPath:メソッド内から

すべてのテーブルビュー メソッドは次のとおりです。

//---set the title for each section---
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {


     //countyIndex returns the number of counties per state
     //in the debugger I checked and the countyIndex is returning the correct number
     //of counties!
    return [countyIndex objectAtIndex:section];

}

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return [countyIndex count];
}

//---set the number of rows in each section---
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    //---get the county in section---
    NSString *county = [countyIndex objectAtIndex:section];

    //---get all models from the county---
    NSPredicate *predicate = 
    [NSPredicate predicateWithFormat:@"countyName == %@", county];
    NSArray *mods = [modelArray filteredArrayUsingPredicate:predicate];

    //---return the number of models from the county---
    return [mods count];    

}
   //models appears to be counted as the number of objects per section


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

        cell = [[UITableViewCell alloc]
                initWithStyle:UITableViewCellStyleDefault
                reuseIdentifier:CellIdentifier];

    }

    // now configure the cell


    //---get the county in the current section---
    NSString *county = [countyIndex objectAtIndex:[indexPath section]];

    //---get all models from the county---
    NSPredicate *predicate = 
    [NSPredicate predicateWithFormat:@"countyName == %@", county];
    NSArray *mods = [modelArray filteredArrayUsingPredicate:predicate];
    NSMutableArray *newModelArray = [[NSMutableArray alloc] init];
     for (NSManagedObject *obj in mods) {
         [newModelArray addObject:[NSString stringWithFormat:@"%@",[obj valueForKey: @"model"]]];
     }


    //get rid of duplicates
    NSArray *objectsWithDuplicates = newModelArray;
    NSSet *duplicatesRemover = [NSSet setWithArray:objectsWithDuplicates];
    models = [duplicatesRemover allObjects];
    models = [models sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];


    UITableViewCell *bgView = [[UITableViewCell alloc] initWithFrame:CGRectZero];

    //cell.contentView.backgroundColor = [UIColor whiteColor];
    bgView.backgroundColor = [UIColor whiteColor];

    cell.backgroundView = bgView;
    cell.layer.borderColor = [[UIColor lightGrayColor] CGColor];      
    cell.layer.borderWidth  = .50;



    if ([models count]>0) {
        //---extract the relevant model from the model object---
        NSString *cellValue = [models objectAtIndex:indexPath.row];
        cell.textLabel.text = cellValue;

        [cell setAccessibilityTraits:UIAccessibilityTraitButton];

    }
    return cell;
}

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    //index path to row that's selected 
    NSIndexPath *myIndexPath = [self.sTable indexPathForSelectedRow];
    UITableViewCell *cell = [self.sTable cellForRowAtIndexPath:myIndexPath];
    labelText = cell.textLabel.text;
    selectedModel = cell.textLabel.text;

}

コンソールからいくつかのコマンドを実行した後:

po [モデル数]

po (int)[indexPath 行]

[models count] が 2 に等しく、[indexPath 行] も 2 に等しい場合に壊れていることがわかります。テーブルのインデックスは 0 から始まるため、2 は実際には 3 であるため、もちろん範囲外になります。

問題は、なぜこれが起こっているのかということです。テーブルの値を切り替えた後、すでにテーブルデータをリロードしており、セクションごとのすべての行数を調べて数えたところ、正しく表示されます。では、他になぜこれが起こっているのでしょうか? 奇妙なことに、テーブルを下にスクロールすると cellForRowAtIndexPath:(NSIndexPath *)indexPath が再呼び出しされた後にこの中断が発生します。

これは、Xcode 4.6.1 のすべてのシミュレーター ios 5.0 - ios 6.1 内で発生します。

**編集:

これはカリフォルニア州とウィスコンシン州でのみ発生することを付け加えておきます。これは絞り込みに役立つと思いましたが、データベースを確認したところ、郡とモデルの数はデバッガーで返されたものと一致しています。

4

1 に答える 1

1

これはcellForRowAtIndexPath、重複を削除するためです。しかし、あなたはそれをしませんnumberOfRows。したがって、 のモデル配列は、 でcellForRow導出されたカウントよりも短くなりますnumberOfRows

これは、DRY が非常に重要なルールである理由の典型的なケースです: 自分自身を繰り返さないでください。同じことを 2 つの異なる方法で実行すると、コードが無駄になり、コードの保守が難しくなるだけでなく、同じことを 2 つの場所で異なる方法で実行するリスクが生じます。特定のセクション (郡) の実際のモデルを導出するコードを除外して、他の 2 つのメソッドが参照するメソッドが1 つだけになるようにする必要があります。(より良いモデルを準備するのがさらに良いでしょう。おそらく、行と配列インデックスの間に常に単純な 1 対 1 の対応があるモデルです。)

于 2013-05-01T22:38:11.370 に答える