-[UITableView _endCellAnimationsWithContext:]のアサーションエラー


89

うまくいけば、これは簡単な修正になるでしょう。私は私が得続けるエラーを理解しようとしています。エラーは以下にリストされており、appdelagateはその下にあります。

どんな助けでもありがたいです。

ありがとう

2012-04-12 21:11:52.669 Chanda [75100:f803] ---のアサーションエラー-[UITableView _endCellAnimationsWithContext:]/SourceCache/UIKit_Sim/UIKit-1914.84/UITableView.m:1037 2012-04-12 21:11:52.671 Chanda [75100:f803] ---キャッチされない例外 ' NSInternalInconsistencyException' によりアプリを終了しています、理由: '無効な更新:セクション0の無効な行数。更新後の既存のセクションに含まれる行数(2)は、更新前にそのセクションに含まれる行数(2)に加えて、さらにまたはそのセクションに挿入または削除された行の数(1挿入、0削除)およびそのセクションに移動またはそこから移動された行の数(0は内側に移動、0は外側に移動)。

#import "AppDelegate.h"

@implementation AppDelegate

@synthesize window = _window;
@synthesize databaseName,databasePath; 

- (BOOL)application: (UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
    self.databaseName = @"Customers.db";

    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentDir = [documentPaths objectAtIndex:0];
    self.databasePath = [documentDir stringByAppendingPathComponent:self.databaseName];
    [self createAndCheckDatabase];

    return YES;
}

- (void)createAndCheckDatabase {
    BOOL success;

    NSFileManager *fileManager = [NSFileManager defaultManager];
    success = [fileManager fileExistsAtPath:databasePath];

    if (success) return; 

    NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:self.databaseName];

    [fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}

@end

3
そのコードをクラスに移動し、おそらくバックグラウンドスレッドで実行する必要があります。とにかく、このエラーは通常、テーブルビューのデータソースによって提供される行数を実際に減らしずに行を削除しようとしたときに発生します。行を削除するときに実際にデータを削除していますか?行を削除しない場合、テーブルビューデータソースの実装を提供できますか?
コンスタンティーノツァロウは

回答:


43

コードのこの部分を表示する理由がわかりません。あなたのエラーは私が想定するコードのこの部分に関連している必要があります

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

おそらく、これらのデータソースメソッドの1つで間違いを犯しています。現在、正確に何が間違っているかを言うことは不可能ですが、私はそれが次のようなものである可能性があると思います:テーブルビューにn行を予約してセットアップし、その後n-1行のみを処理numberOfRowsInSectionするように指示しているとします。cellForRowAtIndexPath

この回答は、正確であるとは限りません。あなたのデータソースの実装を私たちに見せれば、何が起こっているのかを伝えるのがはるかに簡単になります。


26

Sun Tzuが言ったように戦うことなく勝つことが最善です。私の場合、この種のエラーメッセージ(つまり、削除された行と追加された行の不一致)が表示されたときはいつでもデバッグしません。行を再読み込みするような追加の呼び出しを行わないようにします。99%です。このエラーが発生するケース。

これは、このバグが発生する一般的なシナリオです。「」UINavigationControllerと「」がありUITableView、行をクリックするUITableViewと、新しいものがプッシュされます。このエラーは、最後をポップしUITableviewてそのUITableView前に戻ると常に発生します。この時点で、loadIt基本的に行を挿入してを再ロードする関数を不必要に呼び出しますUITableView

これが発生する理由は、loadIt関数をでviewDidAppear:animatedはなく誤って配置したためですviewDidLoadviewDidAppear:animatedUITableView表示されるたびに呼び出され、viewDidLoad一度だけ呼び出されます。


3
ありがとう、よく言った。最初の段落では、同様の問題を解決するために私を正しい軌道に乗せました。
scrrr 2013年

2
それは私の喜びです@scrrr :)
abbood 2013年

この変更により、私は見方を変えました-それを無関係にして問題を修正しました。あなたはロック!
チャーリー

viewDidLoadではなく、viewDidAppearへの称賛。それはまさに私の問題であり、私は数週間それを扱っていました。
GrandSteph 2015

1
Sun Tzuの見積もりを印刷して、画面の上部にテープで貼り付けました。引用してくれて、たくさんの冗長なコードを見つけるのを手伝ってくれてありがとう:)
エイドリアン

24

行を削除するときは、更新時にセクションもチェックすることに注意してください。

- (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView

セクションの最後のアイテムである行を削除したい場合は、代わりにセクション全体を削除する必要があります(そうしないと、セクション数が間違ってこの例外がスローされる可能性があります)。


1
これは純金です!頭に釘が当たる!まさに私の問題です。
ファットマン、2014年

6

numberOfRowsInSectionを決定する配列を更新することを忘れないでください。アニメートして削除する前に更新する必要があります

セクション全体を削除する必要があるため、セクションの行数が1かどうかを確認します。

誰かがこの答えを明確にできる場合は、私を修正してください。

[self.tableView beginUpdates];
if ([tableView numberOfRowsInSection:indexPath.section] == 1) {

   [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];
} else {

   [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
[self.tableView endUpdates];

4

各セクション要素を別々の配列に配置します。次に、それらを別の配列(arrayWithArray)に入れます。この問題に対する私の解決策:

[quarantineMessages removeObject : message];
[_tableView beginUpdates];
if([[arrayWithArray objectAtIndex: indPath.section] count]  > 1)
{
    [_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indPath] withRowAnimation:UITableViewRowAnimationBottom];
}
else
{
    [_tableView deleteSections:[NSIndexSet indexSetWithIndex:indPath.section]
              withRowAnimation:UITableViewRowAnimationFade];
}
[_tableView endUpdates];

1
私にとってそれを解決したのは最初と最後のアップデートでした、ありがとう!
マークW

2
セクションが空になり、代わりにアニメーション化する必要があることを知りませんでした。くそー!ありがとう!
dvkch 2014年

1
この答えから多くの助けを借りて私のコードを動作させました。以下に投稿してください。
love2script12 14年

2

同じエラーが発生しました。

私は次の行を使用していました

UINib *myCustomCellNib = [UINib nibWithNibName:@"CustomNib" bundle:nil];
[tableView registerNib:myCustomCellNib forCellReuseIdentifier:@"CustomNib"];

同じクラスに関連付けられている別のnibがあったので、viewDidLoadメソッドにnibを登録します。したがって、行

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"GBFBLoadingCell"];

viewDidLoadでnibを登録しない限り、nilが返されていました。

私の問題は、ファイル「CustomNib.xib」と「CustomNib〜iphone.xib」の属性インスペクターで識別子を設定するのを忘れていたことでした。(より正確には、XCodeの属性インスペクターで識別子を入力した後でEnterキーを押すのを忘れたため、新しい名前を保存できませんでした。)

お役に立てれば。


2
あなたの答えが問題と関係があるとは思いません。
DawnSong 2015

2

NSFetchedResultsController私のようなものを使用し、バックグラウンドスレッドでデータを更新している場合は、デリゲートで更新を開始および終了することを忘れないでください。

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView beginUpdates];
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView endUpdates];
}

2

私は同じエラーがありました、それを試してみると[tableView reloadData]うまくいきました。エラーは実際には行にありました

[TabView insertRowsAtIndexPaths:indexPathsArray withRowAnimation:UITableViewRowAnimationRight];

indexPathの値を確認しようとしたところ、必要に応じて正しくありませんでした。

の値を変更して修正しましたindexPathsArray

お役に立てれば 。


1

UITableViewDataSourceプロトコルメソッドの1つである可能性があります

ために

- tableView:numberOfRowsInSection:

の合計または結果に等しい整数を返す必要があります

-insertRowsAtIndexPaths:withRowAnimation:および/または-deleteRowsAtIndexPaths:withRowAnimation

ために

- numberOfSectionsInTableView:

の合計または結果に等しい整数を返す必要があります

-insertRowsAtIndexPaths:withRowAnimation: および/または -deleteSections:withRowAnimation:


0

コアデータベースにも同じ問題がありました。多くのFRCを使用している場合は、numberOfSectionsInTableViewの各条件内のテーブルビューをリロードするだけです。


2
Core Dataにもこの問題があります。レシピを詳しく教えてください。
Drux、2015

0

SwiftとFRCでサポートされているデータストアを使用して情報を管理しているときに、この問題が発生しました。単純なチェックを削除操作に追加して現在のindexPath.sectionを評価すると、無関係な呼び出しを回避できます。この問題が発生する理由は理解できたと思います...基本的に、データセットが空の場合は常にメッセージを一番上の行にロードします。これは、偽の列があるため、1つずつ問題が発生します。

私の解決策

... delete my entity, save the datastore and call reloadData on tableView
//next I add this simple check to avoid calling deleteRows when the system (wrongly) determines that there is no section.

       if indexPath.section > 0 {

        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .None)

            }

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.