5

私はこのエラーを探していましたが、同様の動作をするいくつかの投稿を見つけましたが、問題を解決する解決策はありませんでした.

セクションを持つ UITableViewController (SB で静的として宣言されている) があります: セクション 0 (レシピ) は 4 つのセルで静的であり、セクション 1 (フレーバー) は動的である必要があります

ストーリーボードのスクリーンショット

これは私がテストに使用しているコードです:

- (void)viewDidLoad {
    [super viewDidLoad];

    rows = [[NSMutableArray alloc] initWithArray:@[@"test",@"test",@"test",@"test",@"test",@"test",@"test"]];
}


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
    return 2;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
    switch (section) {
        case 0:
        return 4;
        break;
        case 1:
        return rows.count;
        break;

        default:
        break;
    }

    return 1;
}

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

    UITableViewCell *cell;

    switch (indexPath.section) {
        case 0:
        return [super tableView:tableView cellForRowAtIndexPath:indexPath];
        break;

        case 1:

        cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
        if (!cell)
        {
// create a cell
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
        }
        cell.textLabel.text = [rows objectAtIndex:indexPath.row];
        return cell;

        default:
        break;
    }

    return cell;
}

実行時に発生するエラーは次のとおりです: 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'

私はどこか小さな何かを見逃していることを知っています.誰かが私を助けることができますか?

本当にありがとう

4

4 に答える 4

9

実際の問題は、動的および静的な tableViewController がどのように機能するかです。

動的 UITableViewController を作成すると、ほとんどのメソッドは nil または 0 または別のデフォルト値を返します。したがって、UITableViewController サブクラスでそれらを上書きしなくても、悪いことは何も起こりません。

静的な UITableViewController を作成すると、ほとんどのメソッドがストーリーボードに何を返すかを「尋ねます」。実際には、必要なすべてのデータを含むバッキング ストアとして、おそらくプライベート アレイのようなものがあります。また、このバッキング ストアをクエリするメソッドを上書きしない場合、既定の実装では、存在しないインデックスのオブジェクトを配列に要求します。


あなたの問題は、tableView に 2 つのセクションといくつかの行があることを伝えることです。したがって、tableView は静的な UITableViewController に、2 番目のセクションの 2 行目のセルの高さなどを尋ねます。ただし、この indexPath は、静的な tableView で使用されるバッキング ストアには存在しません (2 番目のセクションに 1 つの行しか入れていないため)。

したがって、tableView が静的テーブル ストアに存在しない情報にアクセスする必要がある場合は、dataSource メソッドとデリゲート メソッドをいくつか実装し、独自の値を返す必要があります。

例外のコール スタックを見ると、これらのメソッドを確認できるはずです。

例えば:

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
(
    0   CoreFoundation    0x000000010ebaaf35 __exceptionPreprocess + 165
    1   libobjc.A.dylib   0x000000010e843bb7 objc_exception_throw + 45
    2   CoreFoundation    0x000000010eaa301e -[__NSArrayI objectAtIndex:] + 190
    3   UIKit             0x000000010f4dc856 -[UITableViewDataSource tableView:heightForRowAtIndexPath:] + 109
    4   UIKit             0x000000010f21026b __66-[UISectionRowData refreshWithSection:tableView:tableViewRowData:]_block_invoke + 302
    5   UIKit             0x000000010f20f8fe -[UISectionRowData refreshWithSection:tableView:tableViewRowData:] + 4125
    6   UIKit             0x000000010f214e45 -[UITableViewRowData rectForFooterInSection:heightCanBeGuessed:] + 320
    7   UIKit             0x000000010f214f3a -[UITableViewRowData heightForTable] + 56

コール スタックのインデックス 3 で、例外を発生させたコード-[UITableViewDataSource tableView:heightForRowAtIndexPath:]が呼び出されたことがわかります。objectAtIndex:これは、呼び出しをバックエンド ストアに中継する方法の 1 つです。したがって、このメソッドを実装して、何か役に立つものを返す必要があります。そして、例外がなくなるまで続行します。

必要なメソッドの数は、tableView の構成によって異なります。通常これらの例外を引き起こす 4 つを実装したので、上書きされていない UITableViewDataSource/Delegate メソッドが原因で発生する例外が他にもある場合に従うべきパターンがわかります。

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    CGFloat height = 0;
    if (section == 0) {
        // static section
        height = [super tableView:tableView heightForHeaderInSection:section];
    }
    return height;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    CGFloat height = 0;
    if (section == 0) {
        // static section
        height = [super tableView:tableView heightForFooterInSection:section];
    }
    return height;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    CGFloat height = 44;
    if (indexPath.section == 0) {
        // static section
        height = [super tableView:tableView heightForRowAtIndexPath:indexPath];
    }
    return height;
}

- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSInteger indentationLevel = 0;
    if (indexPath.section == 0) {
        // static section
        indentationLevel = [super tableView:tableView indentationLevelForRowAtIndexPath:indexPath];
    }
    return indentationLevel;
}

静的コンテンツをコードからさらに独立させるためのちょっとしたトリックを次に示します。

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section == 0) {
        // static section
        return [super tableView:tableView numberOfRowsInSection:section];
    }
    return self.objects.count;
}

動的セルと静的セルを混在させると、呼び出しsuperが非常に便利になります。

于 2014-12-03T15:56:03.607 に答える
2

この振る舞いは自明ではないようです。ですべてのメソッドをオーバーライドする必要がある場合がありますNSIndexPath。詳細については、このディスカッションこのディスカッションを参照してください。

于 2014-12-03T15:16:23.070 に答える
0

スーパーへの呼び出しを行の高さの UITableViewAutomaticDimension に置き換え、推定された行の高さのデリゲート メソッドを追加しました。iOS 9 では、iOS8 で自動的に展開された行が展開されないという問題がありました。私の静的セルも動的な高さであり、動的セルは高さが固定されています。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:    (NSIndexPath *)indexPath {
CGFloat height = 44;
if (indexPath.section == 0) {
    // static section
    height = UITableViewAutomaticDimension;
}
return height;

}

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 44;

}

于 2016-02-10T22:29:22.110 に答える
0

それで、このエラーが発生する理由を見つけたようです。問題は、私がそれを正しく解決したかどうか、またはプログラムで行う別の方法があるかどうかです...

私の解決策は次のとおりです。SBで、動的にする必要があるセクションを選択し、含まれる最大行数を指定します。私の場合、ユーザーが 30 を超えるフレーバーをレシピに追加できるようにしたくないので、このセクションに 30 行を指定しました。

アプリを実行すると、配列には 7 つのオブジェクトしかありませんが、セクションの行を 30 に設定しても、配列で定義された 7 つだけがレンダリングされ、他の 23 は表示されません。

そのエラーが発生する理由は、静的セクションと動的セクションを混在させたい場合、機能するためにテーブルを静的に定義する必要があるためです。静的モードと SB では、コードがセクションの SB にあるセルの数を読み取るようです。この数値がデータ配列より小さい場合、NSRangeException が発生します...

今のところ、これが私の解決策です。セルが 30 個を超えないことがわかっているためです。誰かがこの問題をより動的な方法で解決する方法を知っている場合は、お知らせください。

于 2014-12-03T15:06:32.463 に答える