Tôi có một vanilla UITableView
được quản lý bởi một NSFetchedResultsController
để hiển thị tất cả các trường hợp của một thực thể Dữ liệu chính đã cho.tableView: cellForRowAtIndexPath được gọi với nil indexPath sau khi xóa mục
Khi người dùng xóa mục nhập trong chế độ xem bảng bằng cách vuốt qua nó, tableView:cellForRowAtIndexPath:
cuối cùng được gọi trên số UITableViewController
của tôi với số nil
indexPath
. Vì tôi đã không mong đợi nó sẽ được gọi với một nil
indexPath
, ứng dụng bị treo.
Tôi có thể khắc phục sự cố bằng cách kiểm tra giá trị nil
và sau đó trả lại ô trống. Điều này dường như làm việc, nhưng tôi vẫn lo lắng rằng tôi có thể đã xử lý một cái gì đó sai trái. Bất kỳ ý tưởng? Có ai từng nhìn thấy tableView:cellForRowAtIndexPath:
được gọi với số nil
indexPath
không?
Lưu ý rằng điều này chỉ xảy ra khi người dùng xóa từ chế độ xem bảng bằng cách vuốt qua ô. Khi xóa một mục bằng chế độ chỉnh sửa chế độ xem bảng, nó không xảy ra. Điều gì sẽ khác nhau giữa hai cách để xóa một ô?
Vì vậy, có thực sự là một tình huống OK để có được một nil
indexPath
trong một phương thức ủy nhiệm xem bảng?
Mã bộ điều khiển chế độ xem của tôi thực sự là tiêu chuẩn. Đây là việc xóa:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
[self.moc deleteObject:managedObject];
NSError *error = NULL;
Boolean success = [self.moc save:&error];
if (!success) { <snip> }
// actual row deletion from table view will be handle from Fetched Result Controller delegate
// [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else { <snip> }
}
Điều này sẽ dẫn đến phương pháp NSFetchedResultsController
đại biểu được gọi là:
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeInsert: <snip> break;
case NSFetchedResultsChangeUpdate: <snip> break;
case NSFetchedResultsChangeMove: <snip> break;
}
}
Và tất nhiên, các phương pháp nguồn dữ liệu được xử lý bởi các NSFetchedResultsController
, ví dụ:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
Rất cám ơn.
Cậu xác minh tất cả những được gọi theo thứ tự dự đoán? – Mundi
Hãy thử gọi 'reloadData' trên chế độ xem bảng của bạn trong' tableView: commitEditingStyle: forRowAtIndexPath' ngay lập tức * sau * lưu các thay đổi đối với bối cảnh đối tượng được quản lý. Tôi đã có một vấn đề tương tự với điều này và tải lại xem bảng cố định nó. – Greg