Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 刷新和删除后台线程中的内容错误(NSFetchedResultsController)_Iphone_Uitableview_Nsfetchedresultscontroller - Fatal编程技术网

Iphone 刷新和删除后台线程中的内容错误(NSFetchedResultsController)

Iphone 刷新和删除后台线程中的内容错误(NSFetchedResultsController),iphone,uitableview,nsfetchedresultscontroller,Iphone,Uitableview,Nsfetchedresultscontroller,我正在使用NSFetchedResultsController填充UITableViewController的内容 我使用NSOperation从Web服务收集数据(我使用单独的ManagedObjectContext作为另一个线程) 保存数据时,将调用我的ViewController(即NSFetchedResultsControllerDelegate),并使用mergeChangesFromContextDidSaveNotification合并我的MOC #pragma mark - #

我正在使用NSFetchedResultsController填充UITableViewController的内容

我使用NSOperation从Web服务收集数据(我使用单独的ManagedObjectContext作为另一个线程)
保存数据时,将调用我的ViewController(即NSFetchedResultsControllerDelegate),并使用mergeChangesFromContextDidSaveNotification合并我的MOC

#pragma mark -
#pragma mark Parsers delegate

- (void)parserWillSave:(id)parser{
    TopNewsParser *emp = (TopNewsParser *)parser;
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(parserContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:emp.managedObjectContext];
    [NSFetchedResultsController deleteCacheWithName:@"aLaUne"];
}

- (void)parserDidSave:(id)parser{
    TopNewsParser *emp = (TopNewsParser *)parser;
    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:emp.managedObjectContext];
}

/**
 Notification from the add controller's context's save operation. This is used to update the fetched results controller's managed object context with the new book instead of performing a fetch (which would be a much more computationally expensive operation).
 */
- (void)parserContextDidSave:(NSNotification*)saveNotification {
    DLog(@"");
    NSManagedObjectContext *fetchContext = [_fetchedResultsController managedObjectContext];
    // Merging changes causes the fetched results controller to update its results
    [fetchContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
                                  withObject:saveNotification
                               waitUntilDone:YES]; 


}
对于NSFetchedResultsControllerDelegate,我使用的代码来自CoreDataBooks示例

#pragma mark -
#pragma mark NSFetchedResultsControllerDelegate

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

    [self.tableView beginUpdates];
}


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
    //ALog(@"indexPath: %@ newIndexPath : %@ | type : %d # %@",indexPath,newIndexPath,type,anObject);
    UITableView *tableView = self.tableView;

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

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

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            // Reloading the section inserts a new row and ensures that titles are updated appropriately.
            [tableView 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.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

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


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    UIBarButtonItem *reloadButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh 
                                                                                  target:self                               
                                                                                  action:@selector(refreshTableViewContent)];
    reloadButton.accessibilityLabel = @"Reload";
    self.navigationItem.leftBarButtonItem = reloadButton;

    // The fetch controller has sent all current change notifications, so tell the table view to process all updates.
    [self.tableView endUpdates];

}
#pragma标记-
#pragma标记NSFetchedResultsControllerDelegate
-(void)controllerWillChangeContent:(NSFetchedResultsController*)控制器{
//fetch控制器即将开始发送更改通知,因此请准备表视图以进行更新。
[self.tableView开始更新];
}
-(void)控制器:(NSFetchedResultsController*)控制器didChangeObject:(id)索引路径中的一个对象:(NSIndexPath*)变更类型的indexPath:(NSFetchedResultsChangeType)类型newIndexPath:(NSIndexPath*)newIndexPath{
//ALog(@“indepath:%@newindepath:%@|type:%d#%@),indepath,newindepath,type,anObject);
UITableView*tableView=self.tableView;
开关(类型){
案例NSFetchedResultsChangesInsert:
[tableView InsertRowsatindExpath:[NSArray arrayWithObject:newIndexPath]带RowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]和RowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeUpdate:
[self-configureCell:[tableView cellForRowAtIndexPath:indexPath]atIndexPath:indexPath];
打破
案例NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]和RowAnimation:UITableViewRowAnimationFade];
//重新加载节将插入新行,并确保标题得到适当更新。
[tableView重新加载节:[NSIndexSet IndexSetWithiIndex:NewIndexXPath.section]带RowAnimation:UITableViewRowAnimationFade];
打破
}
}
-(void)控制器:(NSFetchedResultsController*)控制器didChangeSection:(id)sectionInfo atIndex:(nsInteger)ChangeType的sectionIndex:(NSFetchedResultsChangeType)类型{
开关(类型){
案例NSFetchedResultsChangesInsert:
[self.tableView insertSections:[NSIndexSet IndexSetWithiIndex:sectionIndex]带RowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet IndexSetWithiIndex:sectionIndex]带RowAnimation:UITableViewRowAnimationFade];
打破
}
}
-(void)controllerDidChangeContent:(NSFetchedResultsController*)控制器{
UIBarButtonItem*重载按钮=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh
目标:自我
操作:@选择器(refreshTableViewContent)];
reloadButton.accessibilityLabel=@“重新加载”;
self.navigationItem.leftBarButtonItem=重新加载按钮;
//fetch控制器已发送所有当前更改通知,因此请告诉表视图处理所有更新。
[self.tableView endUpdates];
}
我的问题是,当加载新内容时,某个对象被删除了,我的tableView就乱七八糟了!即使我的countOfRow减少1,该行仍然可见:

然后,当我向下滚动时,我的tableview为空(只有4行可见)仍在tableview中,否则它是一个空白的scrollView

在控制台中,我可以看到以下消息

严重的应用程序错误。调用-controllerDidChangeContent时,从NSFetchedResultsController的委托捕获到异常:**-[NSMutableArray removeObjectAtIndex:]:索引0超出了具有userInfo(null)的空数组的界限

在Begging中,我认为这是由于NSFetchedResultsController的缓存造成的,但即使禁用它,我也会遇到同样的问题

有人知道如何解决这个问题吗?

这里也有同样的问题

人们建议使用TopSongs示例代码。修改版本如下:

我想知道我们是否应该在共享数据上使用互斥