tableView endUpdates 在 fetchedResults 更改后崩溃
Posted
技术标签:
【中文标题】tableView endUpdates 在 fetchedResults 更改后崩溃【英文标题】:tableView endUpdates crashes after change in fetchedResults 【发布时间】:2010-12-18 23:46:04 【问题描述】:我有一个应用,当用户首次启动应用时,它会显示一个自定义的无数据单元格。
当用户输入第一个条目时,我的 fetchedResultsController 的 fetchedResults 会被更新,这会导致 no-data-yet 单元格被删除并插入一个数据单元格。
这在过去 (iPhone 3.x) 曾经有效。现在在 ios 4.2 上,调用 endUpdates 后会导致崩溃。没有异常信息或任何可理解的堆栈跟踪。我只知道崩溃是在 _CFTypeCollectionRetain 引起的(可能试图保留一个 NULL)
任何想法如何进行?
这里是相关代码:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
NSLog(@"starting updates");
[self.tableView beginUpdates];
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
switch(type)
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
UITableView *tv = self.tableView;
[tv reloadData];
switch(type)
case NSFetchedResultsChangeInsert:
NSLog(@"insert");
if ([self.tableView numberOfRowsInSection:newIndexPath.section] == 1 &&
[[self.fetchedResultsController fetchedObjects] count] == 1)
NSLog(@"reloading row %d", newIndexPath.row);
[tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[tv insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
else
NSLog(@"inserting new row %d", newIndexPath.row);
[tv insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
NSLog(@"delete");
if ([self.tableView numberOfRowsInSection:newIndexPath.section] == 0 &&
[[self.fetchedResultsController fetchedObjects] count] == 0)
NSLog(@"reloading row %d", newIndexPath.row);
[tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[tv insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
else
NSLog(@"deleting row %d", newIndexPath.row);
[tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
NSLog(@"finishing updates");
[self.tableView endUpdates];
【问题讨论】:
【参考方案1】:在委托方法中
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
您处理插入和删除。对于插入 indexPath
是 nil
。对于删除newIndexPath
是nil
。因此,如果是type== NSFetchedResultsChangeDelete
,则不允许您访问newIndexPath
。
这里不需要调用reloadData
。
【讨论】:
以上是关于tableView endUpdates 在 fetchedResults 更改后崩溃的主要内容,如果未能解决你的问题,请参考以下文章
最后一个单元格上的 UITableView beginUpdate 和 endUpdate 重新加载 tableview
IOS Swift Master Detail Application, managed object, tableView: endUpdates() 调用configureCell() 但崩溃,r
tableView beginUpdates / endUpdates 阻止重新加载整个表,即使是空的
刷新表格时应用程序崩溃(可能是tableView上的调用endUpdates导致崩溃)