【发布时间】:2014-03-31 20:43:58
【问题描述】:
请轻点,这是我第一次发帖。
当我更新子类 NSManagedObject 并使用获取的结果控制器执行保存时,它不是在“didChangeObject”中调用 NSFetchedResultsChangeUpdate,而是调用 NSFetchedResultsChangeDelete。保存工作并更新对象,但随后立即将其从 UITableView 中删除。如果我退出并返回,则该对象会随着更新重新出现在 tableview 中,因此我知道它正在将其保存到 DB。
我正在使用 XCODE 5 为一个简单的任务应用程序开发代码。我使用的是 iPhone 4S 而不是模拟器来测试它。它工作正常,直到我对代码的另一部分进行了一些修改(我认为未连接,现在它不起作用。
我有一个排序顺序,当我更新一个对象并且它改变了排序顺序时,UITableViewCells 的移动有一个很好的动画......现在我必须再次强制获取并执行 [self.表视图重新加载数据]。这是一个 hack,因为我没有任何动画,但这是我可以更新它的唯一方法:
我有一个prepare for segue方法:
- (void) prepareForSegue: (UIStoryboardSegue *) segue sender: (id) sender
{
// configure the destination view controller:
if ( [segue.destinationViewController isKindOfClass: [ShowEditTaskTableViewController class]])
{
if ([sender isKindOfClass:[UITableViewCell class]] )
{
NSIndexPath *indexPath = [self.taskTableView indexPathForCell:sender];
[self.taskTableView deselectRowAtIndexPath:indexPath animated:YES];
// Pass the selected task to the new view controller.
ShowEditTaskTableViewController *detailViewController = segue.destinationViewController;
Task *info = [self.fetchedResultsController objectAtIndexPath:indexPath];
detailViewController.editedObject = info;
}
else
{
NSIndexPath *indexPath = [self.taskTableView indexPathForCell:sender];
[self.taskTableView deselectRowAtIndexPath:indexPath animated:YES];
ShowEditTaskTableViewController *detailViewController = segue.destinationViewController;
Task *info = (Task *)[NSEntityDescription insertNewObjectForEntityForName:@"Task" inManagedObjectContext:self.managedObjectContext];
detailViewController.editedObject = info;
}
}
}
这里没有什么特别的。 “任务”是我的 NSManagedObject。
我有一个倒带(编辑:在评论后将倒带更改为倒带)segue,在它被调用之前,我设置了将设置存储在editedObject中的变量。:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"addNewTaskSave"]) {
// Note: This is an unwind segue to go back to the previous screen.
self.dueDate = self.taskDatePicker.date;
self.description = self.taskDescriptionTextView.text;
self.priority = self.taskPrioritySegment.selectedSegmentIndex;
}
}
在它调用的 RootViewController 中:
- (IBAction)addNewTaskSave:(UIStoryboardSegue *)segue
{
ShowEditTaskTableViewController *controller = segue.sourceViewController;
controller.editedObject.shortDesc = controller.description;
controller.editedObject.priority = @(controller.priority);
controller.editedObject.dueDate = controller.dueDate;
controller.editedObject.completed = @0;
NSError *error;
if (![self.managedObjectContext save:&error]) {
...
}
..... }
它使用标准的 didChangeObject 委托方法。在我明确更改某些内容之前,这一直很好。
现在保存后,它会设置 NSFetchedResultsChangeDelete 选项并删除表格行。
解决方法是添加:
self.fetchedResultsController = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
...
}
[self.taskTableView reloadData];
但是,这意味着实际观察到的只是 Table View 的直接更新,没有动画。
没有此代码,您可以观察到表格行的动画删除。如果我退出并重新启动,我编辑的对象就在那里。
在过去 4 周(我一直在为 IOS 编写代码的时间)一直是我的伙伴,我搜索了 SO,但找不到任何关于这种行为的信息。
任何帮助将不胜感激。
编辑:
在保存之前,controller.editedObject isDeleted = NO, isUpdated = YES,所以我看不出它为什么要设置 NSFetchedResultsControllerChangeDelete。
【问题讨论】:
-
向 NSFetchedResultsChangeDelete 案例添加断点并检查调用堆栈。您也许可以看到删除更改的来源。
-
Matthias - 感谢您的评论。不幸的是,我对 Xcode 不是很精通。我已经设置了一个断点,但不知道如何检查调用堆栈。不过会搜索一下,谢谢
标签: ios core-data uitableview nsfetchedresultscontroller