Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.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
Objective c 已删除的NSManagedObject从tableview中正确删除,然后在保存时重新显示_Objective C_Ios_Core Data_Nsfetchedresultscontroller_Nsmanagedobjectcontext - Fatal编程技术网

Objective c 已删除的NSManagedObject从tableview中正确删除,然后在保存时重新显示

Objective c 已删除的NSManagedObject从tableview中正确删除,然后在保存时重新显示,objective-c,ios,core-data,nsfetchedresultscontroller,nsmanagedobjectcontext,Objective C,Ios,Core Data,Nsfetchedresultscontroller,Nsmanagedobjectcontext,我正在使用NSFetchedResultsController和NSFetchedResultsController委托来驱动UITableViewController/UITableView。单击按钮可通过[managedObjectContext deleteObject:aManagedObject]触发NSManagedObject的删除 NSFetchedResultsControllerDelegate方法将正确激发,并且该行将从UITableView中删除 这就是事情变得奇怪的地方

我正在使用NSFetchedResultsController和NSFetchedResultsController委托来驱动UITableViewController/UITableView。单击按钮可通过
[managedObjectContext deleteObject:aManagedObject]
触发NSManagedObject的删除

NSFetchedResultsControllerDelegate方法将正确激发,并且该行将从UITableView中删除

这就是事情变得奇怪的地方。调用
[managedObjectContext save:&error]
时,调用NSFetchedResultsControllerDelegate方法
控制器:didChangeObject:atIndexPath:forChangeType:newIndexPath:
,将删除的NSManagedObject作为对象(在托管对象上isDeleted为YES)更改类型为NSFetchedResultsChangeInsert,它将删除的NSManagedObject添加回UITableView

我试图通过检查委托方法中的
isDeleted
标志来抑制插入,但这会导致
beginUpdates
endUpdates
断言失败


我是做错了什么还是不正常了?我在什么地方漏了一步吗?

你忘了下面的代码了吗

如果您仍然感到困惑,请参阅苹果的示例代码。我会对你有很大帮助的

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
静态NSString*cellIdentifier=@“cellIdentifier”;
UITableViewCell*单元格=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
如果(单元格==nil){
cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault重用标识符:cellIdentifier]自动释放];
cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
}
[self-configureCell:cell-atIndexPath:indexPath];
返回单元;
}
-(void)configureCell:(UITableViewCell*)单元格atIndexPath:(NSIndexPath*)indexPath{
//配置单元格
MyObject*recipe=(MyObject*)[fetchedResultsController对象索引路径:indexPath];
//做事
}
-(void)控制器:(NSFetchedResultsController*)控制器didChangeObject:(id)索引路径中的一个对象:(NSIndexPath*)变更类型的indexPath:(NSFetchedResultsChangeType)类型newIndexPath:(NSIndexPath*)newIndexPath{
UITableView*tableView=self.tableView;
开关(类型){
案例NSFetchedResultsChangesInsert:
打破
案例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 InsertRowsatindExpath:[NSArray arrayWithObject:newIndexPath]带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];
打破
}
}

我目前找到了一个解决办法:

[managedObjectContext deleteObject:managedObject];
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [managedObjectContext performBlock:^{
        resultsController.delegate = nil;
        [managedObjectContext save:nil];
        resultsController.delegate = self;
    }];
});

这将删除该对象,让我们使用NSFetchedResultsController委托从UITableView中删除该行。之后的调度会断开代理,执行保存,然后重新连接代理。

面对与您完全相同的问题,我可以意识到,只有另一个对象或上下文对已删除对象的单个引用才能使其作为故障保持活动,直到该引用被删除。如果应用程序再次尝试访问该已删除对象,它将崩溃。单个引用可能是删除对象重新出现的原因

在我的例子中,在调用异步删除操作之前释放对要删除的对象的UIViewController实例引用修复了这个问题

// Delete a NSManagedObject.
NSManagedObjectID *objectID = [[managedObject objectID] copy];
// Release all references to the object.
self.managedObject = Nil;
// Asynchronously delete the object.
[self asynchronouslyDeleteManagedObjectWithManagedObjectID:objectID];

忽略
Release对对象的所有引用
部分会使对象在被删除到
NSFetchedResultsController
观察者实例后重新显示为
isDeleted

这是UIManagedDocument的一部分吗?不是。这只是直接的核心数据。你能提供一些代码吗?很难理解操作系统是怎么回事。谢谢。是的,我已经实现了所有的委托方法。它在删除时按预期工作,但当上下文保存时,它会插入已删除的NSManagedObject。
// Delete a NSManagedObject.
NSManagedObjectID *objectID = [[managedObject objectID] copy];
// Release all references to the object.
self.managedObject = Nil;
// Asynchronously delete the object.
[self asynchronouslyDeleteManagedObjectWithManagedObjectID:objectID];