尝试将新表插入到部分中时抛出异常 [英] exception thrown trying to insert new table row into section

查看:183
本文介绍了尝试将新表插入到部分中时抛出异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎遇到一个非常奇怪的问题,只发生在试图插入一个新的NSManagedObject到一个新的部分。基本上我的部分是天,单独的单元格与时间相关联。当我将一个对象移动到当天没有与该日相关联的另一个对象(表行)的那一天时,该表需要创建一个新的部分并移动该行。而不是这种情况发生正常我得到以下:


严重的应用程序错误。在对-controllerDidChangeContent:的调用期间,NSFetchedResultsController的委托捕获了异常。 - - -

为当前没有其他对象的一天插入一个新对象似乎工作正常。



问题似乎在这个代码的某处,但我可以' t似乎弄清楚它有什么问题。 controller:didChangeSection:... 似乎先调用插入和删除然后控制器:didChangeObject:... 使用NSFetchedResultsChangeMove调用。所以顺序是:



NSFetchedResultsChangeInsert(在didChangeSection中)
NSFetchedResultsChangeDelete(在didChangeSection中)
NSFetchedResultsChangeMove(在didChangeObject中)

  / ** 
委派NSFetchedResultsController的方法来响应添加,删除等。
* /

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
//获取控制器即将开始发送更改通知, 。
[self.plainTableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller
didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType :(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
UITableView * tv = self.plainTableView;

switch(type){
case NSFetchedResultsChangeInsert:
[tv insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeDelete:
[tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeUpdate:
[self configureCell:(UITableViewCell *)[tv cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;

case NSFetchedResultsChangeMove:
[tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
//重新加载节将插入一个新行,并确保标题已正确更新。
[tv reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}

- (void)controller:(NSFetchedResultsController *)controller
didChangeSection:(id< NSFetchedResultsSectionInfo>)sectionInfo
atIndex NSUInteger)sectionIndex
forChangeType:(NSFetchedResultsChangeType)type {
switch(type){
case NSFetchedResultsChangeInsert:
[self.plainTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade] ;
break;

case NSFetchedResultsChangeDelete:
[self.plainTableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
//获取控制器已发送所有当前更改通知,视图以处理所有更新。
[self.plainTableView endUpdates];
}



我认为这只是标准模板代码。



实际上,当尝试向已经存在的一天插入新行时也会发生,但插入新行时不会发生/对象的一天不存在。

解决方案

我认为你有一个概念上的问题。



controller:didChange ... 方法应该调用以响应数据模型中的更改由读取结果控制器(FRC)检测。我很确定你的问题在这里是你改变表之前或不改变底层数据。



节和行不是表的属性,它们是FRC结构化的数据的属性。如果需要添加一个节,您需要首先将其添加到数据,然后让FRC委托方法使表更新。该表反映的是数据模型,而不是其他方式。



如果不这样做,FRC将报告错误的节或行数,并导致该表与您看到的错误崩溃。


I seem to be encountering a very odd problem which only occurs when trying to insert a new NSManagedObject into a new section. Basically my sections are days and individual cells are associated with times. When I MOVE an object to a day which doesn't currently have another object (table row) associated with the day, the table needs to create a new section and move the row. Instead of this happening properly I'm getting the following:

Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. * -[NSMutableArray removeObjectAtIndex:]: index 1 beyond bounds [0 .. 0] with userInfo (null)

Inserting a new object for a day that currently has no other objects seems to work fine.

The problem seems to be somewhere in this code, but I can't seem to figure out what's wrong with it. controller:didChangeSection:... seems to get called first with an insert and a delete then controller:didChangeObject:... is called with NSFetchedResultsChangeMove. So the order is:

NSFetchedResultsChangeInsert (in didChangeSection) NSFetchedResultsChangeDelete (in didChangeSection) NSFetchedResultsChangeMove (in didChangeObject)

/**
 Delegate methods of NSFetchedResultsController to respond to additions, removals and so on.
 */

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller is about to start sending change notifications, so prepare the table view for updates.
[self.plainTableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
   atIndexPath:(NSIndexPath *)indexPath
 forChangeType:(NSFetchedResultsChangeType)type
  newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tv = self.plainTableView;

switch(type) {
    case NSFetchedResultsChangeInsert:
        [tv insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;

    case NSFetchedResultsChangeDelete:
        [tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;

    case NSFetchedResultsChangeUpdate:
        [self configureCell:(UITableViewCell *)[tv cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
        break;

    case NSFetchedResultsChangeMove:
        [tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        // Reloading the section inserts a new row and ensures that titles are updated appropriately.
        [tv reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
        break;
}
}

- (void)controller:(NSFetchedResultsController *)controller
  didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex
     forChangeType:(NSFetchedResultsChangeType)type {
    switch(type) {
    case NSFetchedResultsChangeInsert:
        [self.plainTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
        break;

    case NSFetchedResultsChangeDelete:
        [self.plainTableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
        break;
}
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
[self.plainTableView endUpdates];
}

I thought this was all just standard template code though. Does anyone have any idea what might be wrong?

Actually it also happens when trying to insert a new row into a day which already exists, but not when inserting a new row/object for a day that doesn't already exist.

解决方案

I think you have a conceptual problem here.

The controller:didChange... methods are supposed to called in response to a change in the data model as detected by the fetched results controller (FRC). I'm pretty sure your problem here is that you are changing the table before or without changing the underlying data.

Sections and rows are not attributes of the table, they are attributes of the data as structured by the FRC. If you need to add a section, you need to add it first to the data and then let the FRC delegate methods bring the table up to date. The table reflects the data model and not the other way around.

If you do not do it this way, the FRC will report the wrong number of sections or rows and cause the table to crash with the error you saw.

这篇关于尝试将新表插入到部分中时抛出异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆