-[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' 로 인해 앱 종료 , 이유 : 'Invalid update : invalid number of rows in section 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
해당 코드를 클래스로 이동하고 아마도 백그라운드 스레드에서 실행해야합니다. 어쨌든이 오류는 일반적으로 테이블 뷰의 데이터 소스에서 제공하는 행 수를 실제로 줄이지 않고 행을 제거하려고 할 때 발생합니다. 행을 제거 할 때 실제로 데이터를 제거하고 있습니까? 행을 삭제하지 않는 경우 테이블보기 데이터 소스 구현을 제공 할 수 있습니까?
Constantino Tsarouhas 2012

답변:


43

이 코드 부분을 보여 주신 이유를 모르겠습니다. 귀하의 오류는 내가 가정하는 귀하의 코드 에서이 부분에 연결되어야합니다.

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

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

아마도 이러한 데이터 소스 방법 중 하나에서 실수를하고있을 것입니다. 현재 정확히 무엇이 잘못되었는지 말할 수는 없지만 다음과 같을 수 있다고 가정합니다. n 개의 행을 예약하고 설정하고 numberOfRowsInSection싶을 때 테이블 뷰에 말하고 예를 들어 n-1 개의 행만 처리 합니다.cellForRowAtIndexPath

이 답변이 정확하지 못해 죄송합니다. 데이터 소스의 구현을 보여 주면 무슨 일이 일어나고 있는지 쉽게 알 수 있습니다.


26

Sun Tzu가 말한 것처럼 : 싸우지 않고이기는 것이 가장 좋습니다 . 내 경우에는 이런 종류의 오류 메시지가 표시 될 때마다 (예 : 추가 된 행 사이의 불일치 삭제 등) .. 아무 것도 디버그하지도 않습니다. 단순히 행을 다시로드하는 추가 호출을 피합니다. 이 오류가 발생하는 경우.

이것은이 버그가 발생하는 일반적인 시나리오입니다. 나는 a UINavigationController가 있고 UITableView, 행을 클릭하면 새로운 것을 푸시하는 식 UITableView입니다. 이 오류는 마지막을 팝하고 이전 UITableview으로 돌아갈 때 항상 발생합니다. UITableView이 시점에서 loadIt기본적으로 행을 삽입하고 UITableView.

내가 잘못 내 loadIt 기능을 배치하기 때문에 이런 일이 발생하는 이유는 viewDidAppear:animated것이 아니라 viewDidLoad. viewDidAppear:animatedUITableView표시 될 때마다 호출되며 viewDidLoad한 번만 호출 됩니다 .


3
감사합니다. 귀하의 첫 번째 단락은 유사한 문제를 해결하기 위해 올바른 방향으로 나아갔습니다.
scrrr

2
내 기쁨을 @scrrr :)입니다
abbood

이로 인해 내가 보는 방식이 바뀌 었습니다. 관련성이 없어서 문제가 해결되었습니다. 락!
Charlie

viewDidLoad보다는 viewDidAppear에 대한 명성. 그것은 정확히 제 문제 였고 몇 주 동안 그것을 다루었습니다.
GrandSteph 2015 년

1
나는 당신의 손자 인용문을 인쇄하여 내 화면 상단에 테이프로 붙였습니다. 견적을 보내 주셔서 감사하고 중복 코드를 찾는 데 도움을 주셨습니다. :)
Adrian

24

행을 제거 할 때 다음에서 업데이트 할 때 섹션도 확인합니다.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView

섹션의 마지막 항목 인 행을 제거하려면 대신 전체 섹션을 제거해야합니다 (그렇지 않으면 섹션 수가 잘못되어이 예외가 발생할 수 있음).


1
이것은 순금입니다! 머리에 못을 박았다! 정확히 내 문제.
phatmann

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
나를 위해 그것을 해결 한 시작 및 끝 업데이트였습니다. 감사합니다!
Mark W

2
섹션이 비어 있고 대신 애니메이션이 필요한지 몰랐습니다. 젠장! 감사!
dvkch 2014

1
이 답변에서 많은 도움을 받아 코드를 작성했습니다. 아래에 게시하십시오.
love2script12 2014

2

나는 같은 오류가 있었다.

나는 다음 줄을 사용하고 있었다

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

동일한 클래스와 관련된 다른 펜촉이 있었기 때문에 viewDidLoad 메서드에 펜촉을 등록했습니다. 따라서 라인

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

viewDidLoad에 펜촉을 등록하지 않으면 nil을 반환했습니다.

내 문제는 내 파일 "CustomNib.xib"및 "CustomNib ~ iphone.xib"에 대한 속성 검사기에서 식별자를 설정하는 것을 잊었다는 것입니다. (또는 더 정확하게는 XCode의 속성 검사기에 식별자를 입력 한 후 Enter 키를 누르는 것을 잊었 기 때문에 새 이름이 저장되지 않았습니다.)

도움이 되었기를 바랍니다.


2
귀하의 답변이 문제와 관련이 없다고 생각합니다.
DawnSong

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프로토콜 방법 중 하나 일 수 있습니다.

에 대한

- tableView:numberOfRowsInSection:

합계 또는 결과와 같은 정수를 반환해야합니다.

-insertRowsAtIndexPaths:withRowAnimation:및 / 또는 -deleteRowsAtIndexPaths:withRowAnimation:

에 대한

- numberOfSectionsInTableView:

합계 또는 결과와 같은 정수를 반환해야합니다.

-insertRowsAtIndexPaths:withRowAnimation: 및 / 또는 -deleteSections:withRowAnimation:


0

Core Data base에서 동일한 문제가 발생했습니다. FRC를 많이 사용하는 경우 numberOfSectionsInTableView의 각 조건 내에서 tableview를 다시로드하면됩니다.


2
Core Data에도이 문제가 있습니다. 레시피에 대해 자세히 설명해 주시겠습니까?
Drux

0

Swift와 FRC 지원 데이터 저장소를 사용하여 정보를 관리하는 동안 이런 일이 발생했습니다. 현재 indexPath.section을 평가하기 위해 삭제 작업에 간단한 검사를 추가하면 불필요한 호출을 피할 수있었습니다. 이 문제가 발생하는 이유를 이해한다고 생각합니다. 기본적으로 데이터 세트가 비어있을 때마다 맨 위 행에 메시지를로드합니다. 이것은 가짜 행이 있기 때문에 하나의 문제를 만듭니다.

내 솔루션

... 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.