Xác nhận không thành công trong - [UITableView _endCellAnimationsWithContext:]


89

Hy vọng rằng đây sẽ là một sửa chữa nhanh chóng. Tôi đã cố gắng tìm ra lỗi mà tôi tiếp tục mắc phải. Lỗi được liệt kê bên dưới và thẻ gắn thẻ bên dưới lỗi đó.

Bất kỳ trợ giúp được đánh giá cao.

Cảm ơn

2012-04-12 21: 11: 52.669 Chanda [75100: f803] --- Xác nhận thất bại trong -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1914.84/UITableView.m:1037 2012-04-12 21: 11: 52.671 Chanda [75100: f803] --- Đang chấm dứt ứng dụng do không có ngoại lệ ' NSInternalInconsistencyException' , lý do: 'Cập nhật không hợp lệ: số hàng không hợp lệ trong phần 0. Số hàng có trong phần hiện có sau khi cập nhật (2) phải bằng số hàng có trong phần đó trước khi cập nhật (2), cộng hoặc trừ số hàng được chèn hoặc xóa khỏi phần đó (1 được chèn, 0 bị xóa) và cộng hoặc trừ số hàng được chuyển vào hoặc ra khỏi phần đó (0 được chuyển vào, 0 được chuyển ra ngoài). '

#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
Bạn nên di chuyển mã đó đến các lớp và có thể thực thi nó trong một chuỗi nền. Dù sao, lỗi này thường phát sinh khi bạn cố gắng loại bỏ các hàng mà không thực sự giảm số hàng như được cung cấp bởi nguồn dữ liệu của chế độ xem bảng. Bạn có thực sự xóa dữ liệu khi xóa các hàng không? Nếu bạn không xóa bất kỳ hàng nào, bạn có thể cung cấp triển khai nguồn dữ liệu chế độ xem bảng của mình không?
Constantino Tsarouhas

Câu trả lời:


43

Tôi không hiểu lý do để bạn cho chúng tôi xem phần mã này. Lỗi của bạn phải được kết nối với phần này trong mã của bạn, tôi giả sử

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

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

Có thể bạn đang mắc lỗi trong một trong các phương pháp nguồn dữ liệu này. Hiện tại không thể nói chính xác điều gì là sai nhưng tôi cho rằng nó có thể là một cái gì đó như: Bạn đang nói với chế độ xem bảng trong numberOfRowsInSectionbạn muốn có n hàng được bảo lưu và thiết lập và trong cellForRowAtIndexPathđó bạn chỉ xử lý n - 1 hàng chẳng hạn.

Xin lỗi rằng câu trả lời này không thể chính xác như nó phải được. Nếu bạn cho chúng tôi thấy việc triển khai nguồn dữ liệu của bạn, sẽ dễ dàng hơn nhiều để biết điều gì đang xảy ra.


26

Giống như Tôn Tử đã nói : tốt nhất là chiến thắng mà không cần đánh nhau . Trong trường hợp của tôi bất cứ khi nào tôi thấy loại thông báo lỗi này (tức là sự khác biệt giữa các hàng được thêm vào đã bị xóa, v.v.) .. Tôi thậm chí không gỡ lỗi bất kỳ thứ gì .. Tôi chỉ tránh thực hiện lệnh gọi bổ sung đó khi tôi tải lại các hàng, v.v. đó là 99% các trường hợp mà lỗi này xảy ra.

Đây là một tình huống phổ biến khi lỗi này xảy ra: Tôi có một UINavigationControllervà nó có một UITableView, khi tôi nhấp vào một hàng, nó sẽ đẩy một hàng mới UITableView, v.v. Lỗi này luôn xảy ra với tôi khi tôi bật cuối cùng UITableviewvà quay lại UITableViewtrước đó, tại thời điểm này, tôi thực hiện một lệnh gọi không cần thiết đến loadIthàm về cơ bản sẽ chèn các hàng và bắt đầu lại UITableView.

Lý do điều này xảy ra là do tôi đặt sai hàm loadIt của mình vào viewDidAppear:animatedchứ không phải viewDidLoad. viewDidAppear:animatedđược gọi mỗi khi UITableViewhiển thị, viewDidLoadchỉ được gọi một lần.


3
Cảm ơn, cũng nói. Đoạn đầu tiên của bạn đã đưa tôi đi đúng hướng để giải quyết một vấn đề tương tự.
scrrr,

2
nó @scrrr niềm vui của tôi :)
abbood

Điều này thay đổi cách tôi nhìn nhận nó - nó đã khắc phục sự cố bằng cách làm cho nó không còn liên quan. Bạn rock!
Charlie

Kudo là viewDidAppear chứ không phải viewDidLoad. Đó chính xác là vấn đề của tôi và tôi đã giải quyết nó trong nhiều tuần.
GrandSteph

1
Tôi đã in câu nói Tôn Tử của bạn ra và dán nó lên đầu màn hình. Cảm ơn bạn đã trích dẫn và giúp tôi tìm kiếm rất nhiều mã thừa :)
Adrian

24

Khi xóa các hàng, hãy nhớ rằng nó cũng kiểm tra các phần khi cập nhật, trong:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView

Nếu bạn muốn xóa một hàng là mục cuối cùng trong một phần, bạn cần phải xóa toàn bộ phần đó thay thế (nếu không nó có thể bị sai số phần và bỏ qua ngoại lệ này).


1
Đây là vàng nguyên khối! Đinh đập vào đầu! Chính xác là vấn đề của tôi.
phatmann

6

Đừng quên cập nhật mảng xác định numberOfRowsInSection của bạn. Nó cần được cập nhật trước khi bạn tạo hoạt ảnh và xóa

Chúng tôi kiểm tra xem số hàng trong phần là 1 vì chúng tôi sẽ phải xóa toàn bộ phần.

Hãy sửa cho tôi nếu bất cứ ai có thể làm cho câu trả lời này rõ ràng hơn.

[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

Tôi đặt từng phần tử phần trong các mảng riêng biệt. Sau đó đặt chúng vào một mảng khác (arrayWithArray). Giải pháp của tôi ở đây cho vấn đề này:

[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
đối với tôi, đó là bản cập nhật bắt đầu và kết thúc đã giải quyết nó, cảm ơn!
Mark W,

2
Tôi đã không biết rằng phần này trở nên trống rỗng và cần phải tạo hiệu ứng cho nó thay vào đó ... Chết tiệt! cảm ơn!
dvkch

1
Có mã của tôi để làm việc với rất nhiều trợ giúp từ câu trả lời này. Đăng nó dưới đây.
love2script12

2

Tôi đã có những lỗi giống nhau.

Tôi đã sử dụng những dòng sau

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

để đăng ký nib trong phương thức viewDidLoad, vì tôi có một nib khác cũng được liên kết với cùng một lớp. Do đó, dòng

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

đã trả về nil trừ khi tôi đăng ký nib trong viewDidLoad.

Vấn đề của tôi là tôi đã quên đặt số nhận dạng trong trình kiểm tra thuộc tính cho tệp "CustomNib.xib" và "CustomNib ~ iphone.xib" của tôi. (Hay chính xác hơn là tôi đã quên nhấn enter sau khi nhập mã định danh trong trình kiểm tra thuộc tính trong XCode, do đó tên mới không lưu được.)

Hi vọng điêu nay co ich.


2
Tôi KHÔNG nghĩ rằng câu trả lời của bạn có liên quan đến vấn đề.
DawnSong

2

Nếu bạn đang sử dụng NSFetchedResultsControllergiống tôi và cập nhật dữ liệu trong chuỗi nền, đừng quên bắt đầu và kết thúc cập nhật trong ủy quyền:

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

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

2

Tôi đã gặp lỗi tương tự, mà khi thử với [tableView reloadData]nó hoạt động tốt. Lỗi thực sự nằm trong dòng

[TabView insertRowsAtIndexPaths:indexPathsArray withRowAnimation:UITableViewRowAnimationRight];

Khi tôi cố gắng kiểm tra các giá trị indexPath, chúng không đúng như yêu cầu.

Tôi đã sửa nó bằng cách thay đổi các giá trị trong indexPathsArray.

Hi vọng điêu nay co ich .


1

Nó có thể là một trong những UITableViewDataSourcephương thức giao thức

Đối với

- tableView:numberOfRowsInSection:

nó sẽ trả về một số nguyên bằng tổng hoặc kết quả của

-insertRowsAtIndexPaths:withRowAnimation:và / hoặc -deleteRowsAtIndexPaths:withRowAnimation:

Đối với

- numberOfSectionsInTableView:

nó sẽ trả về một số nguyên bằng tổng hoặc kết quả của

-insertRowsAtIndexPaths:withRowAnimation: và / hoặc -deleteSections:withRowAnimation:


0

Tôi đã gặp vấn đề tương tự với cơ sở Dữ liệu cốt lõi. Nếu sử dụng nhiều FRC, bạn chỉ cần tải lại tableview bên trong mỗi điều kiện trong numberOfSectionInTableView.


2
Tôi cũng gặp vấn đề này với Dữ liệu cốt lõi. Bạn có thể vui lòng giải thích về công thức của bạn.
Drux

0

Tôi vừa gặp chuyện này khi sử dụng Swift và một kho dữ liệu được FRC hỗ trợ để quản lý thông tin. Thêm một kiểm tra đơn giản vào thao tác xóa để đánh giá phần indexPath.section hiện tại đã cho phép tôi tránh một cuộc gọi không liên quan. Tôi nghĩ rằng tôi hiểu tại sao sự cố này xảy ra ... Về cơ bản, tôi tải một thông báo vào hàng trên cùng bất cứ khi nào tập dữ liệu của tôi trống. Điều này tạo ra một sự cố do có một hàng giả.

Giải pháp của tôi

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

            }

0

Chỉ cần kiểm tra xem bạn có gọi [yourTableView reloadData] không; sau khi sửa đổi mảng giá trị.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.