由于未捕获的异常“NSInternalInconsistencyException"而终止应用程序,原因:“在索引 0 的部分中索引 3 处没有对象" [英] Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no object at index 3 in section at index 0'

查看:13
本文介绍了由于未捕获的异常“NSInternalInconsistencyException"而终止应用程序,原因:“在索引 0 的部分中索引 3 处没有对象"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难修复这个错误.

由于未捕获的异常NSInternalInconsistencyException"而终止应用,原因:索引 0 处的部分中索引 3 处没有对象"

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no object at index 3 in section at index 0'

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

That error exist when I delete all my Entity in coredata and refetch it.

调用 API

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

[api requestForMenuCategory:@"details" managedObjectContext:self.managedObjectContext delegate:self];

当 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];

}

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

Number of fetch says it's 0 but I dont' know why I still have a data in my tableview and after awhile it crashes

编辑

这是我在节中的行数,我没有节数,因为未实现时默认为 1

Here's my number of row in section and I don't have number of section since default is 1 when not implemented

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

return [[_fetchedResultsController fetchedObjects] count];

}

编辑 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) 

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

ADDITIONAL NOTE Cell for row is being called but fetchedobject is 0

推荐答案

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

The problem is inside your configureCell:atIndexPath method. Unfortunately the implementation that is provided in the Core Data Xcode templates has a few bugs. Your crash is one of them.

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

The NSFetchedResultsController method objectAtIndexPath: is not very safe to call. If you give it an NSIndexPath that is out of range it will crash with the very exception you are seeing. This is mentioned in the class reference:

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

If indexPath does not describe a valid index path in the fetch results, an exception is raised.

这就像访问数组一样:无论何时通过索引访问数组,都应该先进行边界检查.objectAtIndexPath: 的边界检查如下所示:

This is just like access to an array: whenever you access an array by an index, you should do a bounds check first. A bounds check for objectAtIndexPath: would look like:

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];
    }
}

这有点复杂,但很有必要.这解决了异常.

And that's a bit complicated, but necessary. That solves the exception.

您收到异常的原因是 NSFetchedResultsController 的状态与 tableview 的状态不同步.当你的崩溃发生时,tableView 只是询问你的委托方法(numberOfSectionsInTableViewtableView:numberOfRowsInSection: 的行数和节数.当它询问时,NSFetchedResultsController 有数据它,并给出正值(1 部分,3 行).但是在发生这种情况和崩溃之间,NSFetchedResultsController 表示的实体已从 NSManagedObjectContext 中删除.现在 cellForRowAtIndexPath: 正在被调用过时的 indexPath 参数.

The reason you are getting an exception is that the state of the NSFetchedResultsController is getting out of sync with the state of the tableview. When your crash happens the tableView just asked your delegate methods (numberOfSectionsInTableView and tableView:numberOfRowsInSection: for the number of rows and sections. When it asked that, the NSFetchedResultsController had data in it, and gave positive values (1 section, 3 rows). But in-between that happening and your crash, the entities represented by the NSFetchedResultsController were deleted from the NSManagedObjectContext. Now cellForRowAtIndexPath: is being called with an outdated indexPath parameter.

看起来 egoRefreshScrollViewDataSourceDidFinishedLoading 导致 tableView 通过调整滚动视图的内容视图来重建 - 并且 cellForRowAtIndexPath: 被调用 - before 你重新获取并重新加载你的 tableView.这需要在 egoRefreshScrollViewDataSourceDidFinishedLoading 执行之前发生.egoRefreshScrollViewDataSourceDidFinishedLoading 导致 cellForRowAtIndexPath: 用过时的索引路径调用.

It looks like egoRefreshScrollViewDataSourceDidFinishedLoading is causing the tableView to be rebuilt by adjusting the content view of the scroll view - and cellForRowAtIndexPath: to be called - before you refetch and reload your tableView. That needs to happen before whatever egoRefreshScrollViewDataSourceDidFinishedLoading is doing. egoRefreshScrollViewDataSourceDidFinishedLoading is causing cellForRowAtIndexPath: to be called with stale index paths.

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

The real problem may lie in your NSFetchedResultsControllerDelegate methods. When your entities are being deleted, those should be getting called to remove items from the tableView. That does not seem to be happening here.

不过,将您的 [self.tableView reloadData]; 上移一行:

The short version though, move your [self.tableView reloadData]; up one line:

[self.tableView reloadData];
[_refreshHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:self.tableView];

这篇关于由于未捕获的异常“NSInternalInconsistencyException"而终止应用程序,原因:“在索引 0 的部分中索引 3 处没有对象"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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