更新:在评论中有人指出我不必要地分派(dispatch)到主线程。在删除调度和不必要的 begin/end updates 之后,现在当我尝试删除一个单元格时,它调用 didChangeObject with case NSFetchedResultsChangeUpdate (相反到 NSFetchedResultsChangeDelete),它调用 configureCell。
导致程序崩溃的行是 CollectedLeaf* theCollectedLeaf = [collectionFetchedResultsController objectAtIndexPath:indexPath]; 在下面的方法中。崩溃日志是,部分列表中索引 20 处没有部分。
- (void)configureCell:(SpeciesCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
CollectedLeaf* theCollectedLeaf = [collectionFetchedResultsController objectAtIndexPath:indexPath];
[cell setCollectedLeaf:theCollectedLeaf];
}
每次我滑动以从表格中删除一个单元格时,我都会收到一个无效更新:部分中的行数无效错误。我在 controllerDidChangeContent 中的 [_table endUpdates] 处专门获取了断点。
在许多 SO 帖子中,出现此错误的原因是在从表中删除行之前,对象尚未从数据源中删除。我在 commitEditingStyle 中从数据源中删除对象,它在 didChangeObject 中的 deleteRowsAtIndexPaths 之前调用。
尽管有我的命令,但我仍然收到 Invalid update 的事实让我认为我没有正确/成功地从数据源中删除它。我还是 iOS 的新手 - 如何确保某个对象已从我的核心数据中删除?
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
// The fetch controller is about to start sending change notifications, so prepare the table view for updates.
[_table beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
switch(type) {
case NSFetchedResultsChangeInsert:
[_table beginUpdates];
[_table insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
[_table endUpdates];
break;
case NSFetchedResultsChangeDelete:
NSLog(@"delete called");
[_table deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
// [self configureCell:[_table cellForRowAtIndexPath:indexPath]
// atIndexPath:indexPath];
[_table reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
NSLog(@"fetched update");
break;
case NSFetchedResultsChangeMove:
[_table deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[_table insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
switch(type)
{
case NSFetchedResultsChangeInsert:
[_table insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[_table deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeMove:
break;
case NSFetchedResultsChangeUpdate:
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[_table endUpdates];
}
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(_segmentedControl.selectedSegmentIndex == 1) {
NSLog(@"index path at editingStyleForRowAtIndexPath %@", indexPath);
return UITableViewCellEditingStyleDelete;
}
return NULL;
}
- (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
// [super tableView: tableView didEndEditingRowAtIndexPath:indexPath];
if(_segmentedControl.selectedSegmentIndex == 1) {
for (UITableViewCell *cell in [_table visibleCells]) {
for (UIView *subview in cell.contentView.subviews)
[subview.layer removeAllAnimations];
}
}
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
/*Only allow deletion for collection table */
if(_segmentedControl.selectedSegmentIndex == 1) {
if (editingStyle == UITableViewCellEditingStyleDelete)
{
NSLog(@"index path at commitediting style %@", indexPath);
CollectedLeaf* collectedLeaf = [collectionFetchedResultsController objectAtIndexPath:indexPath];
LeafletPhotoUploader * leafletPhotoUploader = [[LeafletPhotoUploader alloc] init];
leafletPhotoUploader.collectedLeaf = collectedLeaf;
if([LeafletUserRegistration isUserRegistered]) {
[leafletPhotoUploader deleteCollectedLeaf:collectedLeaf delegate:self];
}
// Delete the managed object for the given index path
NSManagedObjectContext *context = [collectionFetchedResultsController managedObjectContext];
[context deleteObject:[collectionFetchedResultsController objectAtIndexPath:indexPath]];
// Save the context.
NSError *error;
if (![context save:&error])
{
NSLog(@"Failed to save to data store: %@", [error localizedDescription]);
NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
if(detailedErrors != nil && [detailedErrors count] > 0)
{
for(NSError* detailedError in detailedErrors)
{
NSLog(@" DetailedError: %@", [detailedError userInfo]);
}
}
else
{
NSLog(@" %@", [error userInfo]);
}
}
}
}
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"speciesCell";
SpeciesCell* speciesCell = (SpeciesCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
[self configureCell:speciesCell atIndexPath:indexPath];
speciesCell.labelCheckMark.backgroundColor = [UIColor blackColor];
return speciesCell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
id <NSFetchedResultsSectionInfo> sectionInfo = [[collectionFetchedResultsController sections] objectAtIndex:section];
if([sectionInfo numberOfObjects] == 0){
UILabel *noDataLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, tableView.bounds.size.height)];
noDataLabel.text = @"Press the Snap It! tab to start collecting!";
//Start your collection by tapping on the Snap It! tab.";
noDataLabel.textColor = [UIColor whiteColor];
noDataLabel.textAlignment = NSTextAlignmentCenter;
tableView.backgroundView = noDataLabel;
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}
return [sectionInfo numberOfObjects];
}
最佳答案
objectAtIndexPath 有很多问题,只能在边界检查中调用,所以我现在使用嵌套 if 语句中的核心数据对象完成我的所有工作
CollectedLeaf* theCollectedLeaf = nil;
if ([[collectionFetchedResultsController sections] count] > [indexPath section]){
id <NSFetchedResultsSectionInfo> sectionInfo = [[collectionFetchedResultsController sections] objectAtIndex:[indexPath section]];
if ([sectionInfo numberOfObjects] > [indexPath row]){
theCollectedLeaf = [collectionFetchedResultsController objectAtIndexPath:indexPath];
//do whatever else I need, delete the object, etc
}
}
如链接帖子所述,
"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."
关于ios 核心数据 : make sure object is deleted from data source,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47340419/
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01 客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02 数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
我正在尝试在Rails上安装ruby,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf