由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'索引0处的索引3处没有对象'

Ron*_*ayo 11 core-data nsfetchedresultscontroller ios

嗨,我很难解决这个错误.

由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'索引0处的索引3处没有对象'

当我删除coredata中的所有实体并重新获取它时,存在该错误.

CALL API

self.fetchedResultsController = nil;
[NSFetchedResultsController deleteCacheWithName:nil];

[api requestForMenuCategory:@"details" managedObjectContext:self.managedObjectContext delegate:self];
Run Code Online (Sandbox Code Playgroud)

当API无法获取数据时执行

    if (![self.fetchedResultsController performFetch:&error]) {
    NSLog(@"%@",[error description]);
        }
else{
    NSLog(@"NUMBER OF FETCH %d",[[_fetchedResultsController fetchedObjects] count]);
    [_refreshHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:self.tableView];
    [self.tableView reloadData];

}
Run Code Online (Sandbox Code Playgroud)

获取的数量说它是0,但我不知道为什么我的tableview中仍然有数据,过了一段时间它崩溃了

编辑

这是我的部分行数,我没有部分的数量,因为默认值为1时没有实现

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

return [[_fetchedResultsController fetchedObjects] count];
Run Code Online (Sandbox Code Playgroud)

}

编辑2

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no object at index 3 in section at index 0'
*** First throw call stack:
(
    0   CoreFoundation                      0x00df65e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x042a08b6 objc_exception_throw + 44
    2   CoreData                            0x03310cae -[NSFetchedResultsController objectAtIndexPath:] + 398
    3   DogDuck                             0x0014c692 -[TestMenuViewController configureCell:atIndexPath:] + 146
    4   DogDuck                             0x0014c583 -[TestMenuViewController tableView:cellForRowAtIndexPath:] + 227
    5   UIKit                               0x01e2361f -[UITableView _createPreparedCellForGlobalRow:withIndexPath:] + 412
    6   UIKit                               0x01e236f3 -[UITableView _createPreparedCellForGlobalRow:] + 69
    7   UIKit                               0x01e07774 -[UITableView _updateVisibleCellsNow:] + 2378
    8   UIKit                               0x01e05b1f -[UITableView _setNeedsVisibleCellsUpdate:withFrames:] + 171
    9   UIKit                               0x01e1b111 -[UITableView _rectChangedWithNewSize:oldSize:] + 490
    10  UIKit                               0x01e1b6dd -[UITableView setBounds:] + 279
    11  UIKit                               0x01daac17 -[UIScrollView setContentOffset:] + 690
    12  UIKit                               0x01e1c1d1 -[UITableView setContentOffset:] + 314
    13  UIKit                               0x01dc7cae -[UIScrollView(UIScrollViewInternal) _adjustContentOffsetIfNecessary] + 2622
    14  UIKit                               0x01daad82 -[UIScrollView setContentInset:] + 143
    15  UIKit                               0x01e1c302 -[UITableView setContentInset:] + 280
    16  DogDuck                             0x00133be6 -[EGORefreshTableHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:] + 310
    17  DogDuck                             0x0014c2a8 -[TestMenuViewController doneLoading] + 440
    18  DogDuck                             0x00006192 __66-[BoogieAPI requestForMenuCategory:managedObjectContext:delegate:]_block_invoke + 1266
    19  Foundation                          0x02ce2695 __67+[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]_block_invoke_2 + 151
    20  Foundation                          0x02c42945 -[NSBlockOperation main] + 88
    21  Foundation                          0x02c9b829 -[__NSOperationInternal _start:] + 671
    22  Foundation                          0x02c18558 -[NSOperation start] + 83
    23  Foundation                          0x02c9daf4 __NSOQSchedule_f + 62
    24  libdispatch.dylib                   0x048ac4b0 _dispatch_client_callout + 14
    25  libdispatch.dylib                   0x0489a75e _dispatch_main_queue_callback_4CF + 340
    26  CoreFoundation                      0x00e5ba5e __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 14
    27  CoreFoundation                      0x00d9c6bb __CFRunLoopRun + 1963
    28  CoreFoundation                      0x00d9bac3 CFRunLoopRunSpecific + 467
    29  CoreFoundation                      0x00d9b8db CFRunLoopRunInMode + 123
    30  GraphicsServices                    0x0524c9e2 GSEventRunModal + 192
    31  GraphicsServices                    0x0524c809 GSEventRun + 104
    32  UIKit                               0x01d34d3b UIApplicationMain + 1225
    33  DogDuck                             0x000027cd main + 125
    34  DogDuck                             0x00002745 start + 53
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 
Run Code Online (Sandbox Code Playgroud)

附加注意 正在调用行的单元格,但fetchedobject为0

que*_*ish 38

问题出在你的configureCell:atIndexPath方法里面.不幸的是,Core Data Xcode模板中提供的实现有一些错误.你的崩溃就是其中之一.

NSFetchedResultsController方法objectAtIndexPath:调用不是很安全.如果你给它一个超出范围的NSIndexPath它会崩溃,你看到的异常.这在类引用中提到:

如果indexPath未在获取结果中描述有效的索引路径,则会引发异常.

这就像访问数组一样:无论何时通过索引访问数组,都应该首先进行边界检查.边界检查objectAtIndexPath:看起来像:

id  result  = nil;
if ([[self.fetchedResultsController sections] count] > [indexPath section]){
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:[indexPath section]];
    if ([sectionInfo numberOfObjects] > [indexPath row]){
        result = [self.fetchedResultsController objectAtIndexPath:indexPath];
    }
}
Run Code Online (Sandbox Code Playgroud)

这有点复杂,但有必要.这解决了这个例外.

您获得异常的原因是NSFetchedResultsController的状态与tableview的状态不同步.当你的崩溃发生时,tableView只询问你的委托方法(numberOfSectionsInTableView以及tableView:numberOfRowsInSection:行和节的数量.当它询问时,NSFetchedResultsController中有数据,并给出正值(1节,3行).但是介于两者之间发生和崩溃时,NSFetchedResultsController表示的实体已从NSManagedObjectContext中删除.现在cellForRowAtIndexPath:正在使用过时的indexPath参数进行调用.

重新获取和重新加载tableView 之前,egoRefreshScrollViewDataSourceDidFinishedLoading通过调整滚动视图的内容视图并cellForRowAtIndexPath:进行调用,看起来会导致重建tableView.这需要在任何事情发生之前发生.导致使用陈旧的索引路径调用.egoRefreshScrollViewDataSourceDidFinishedLoadingegoRefreshScrollViewDataSourceDidFinishedLoadingcellForRowAtIndexPath:

真正的问题可能在于你的NSFetchedResultsControllerDelegate方法.当您的实体被删除时,应调用这些实体以从tableView中删除项目.这似乎没有发生在这里.

简短的版本,向上移动[self.tableView reloadData];一行:

[self.tableView reloadData];
[_refreshHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:self.tableView];
Run Code Online (Sandbox Code Playgroud)