【问题标题】:NSFetchedResultsController delegate methods called infinite number of times upon insertNewObjectForEntityForName:inManagedObjectContext:NSFetchedResultsController 委托方法在 insertNewObjectForEntityForName:inManagedObjectContext 上调用了无数次:
【发布时间】:2012-04-08 13:00:34
【问题描述】:

[编辑] 在更准确地查明问题后,我将对此进行更改以更简洁地解释我的问题。

我正在为我的应用程序处理核心数据,但我很难过。它每次都挂在这个方法中。没有崩溃,没有日志,什么都没有。它只是挂起。

- (void)insertNewObject:(id)sender
{
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
    NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
    NSManagedObject *newObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

    Section *newSection = (Section *)newObject;
    newSection.title = @"inserted";


    NSError *error = nil;

    if (![context save:&error]) {

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
}

NSManagedObject *newObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

我发现如果我将 NSLogs 放在这两个委托方法中:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller

他们只是不断被调用无数次。

【问题讨论】:

  • 看起来它可能在您的获取结果控制器委托方法(didChangeContent)中发生了什么?插入方法是从哪里调用的?
  • @jrturton 我的代码中唯一调用 insertNewObjectForEntityForName: 的地方是在上面的 insertNewObject: 方法中,并且我已经通过日志确认 insertNewObject: 仅被调用一次。我在 controllerWillChangeContent: 中拥有的只是 [self.tableView beginUpdates];也在controllerDidChangecntent:我只有[self.tableView endUpdates];
  • 我遇到了同样的问题(无限循环)。我的 NSManagedOjbect 中有一个 cachedCellHeight 瞬态属性。在我的视图控制器中,我使用 tableView 设置 NSFetchedResultController,并计算 tableView:tableView heightForRowAtIndexPath: 中的 cellHeight 并将其保存在 cachedCellHeight 属性中,这会导致无限循环!如果你有同样的问题,也许你应该再次检查你的代码,看看是否有可能导致无限循环(例如更新 NSFetchedResultsControllerDelegate 协议方法中的某些内容!!!)

标签: database core-data save


【解决方案1】:

好的,我想通了。我正在创建一个无限循环。

这个委托方法被调用:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller

然后这最终会被调用,因为我调用了 [self.tableView beginUpdates];在委托方法中。

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath

    {
        Section *object = [self.fetchedResultsController objectAtIndexPath:indexPath];
        object.title = [NSString stringWithFormat:@"Chapter %i", indexPath.row];
        cell.textLabel.text = object.title;

    }

那么这个委托方法:

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller

问题是我实际上在更新内容时更改了 NSManagedObject 的属性

object.title = [NSString stringWithFormat:@"Chapter %i", indexPath.row];

这导致 controllerWillChangeContent: 再次被调用,创建了一个不断循环的循环。

【讨论】:

  • 干得好!我想知道这个结果会如何。希望我对委托方法的建议有所帮助。
  • 你是怎么解决这个问题的?您是否在更新内容时仍然更新托管对象的属性时对其进行了整理?还是你改变了代码的逻辑?
  • 在更新内容时不改变“NSManagedObject 的属性”
猜你喜欢
  • 2013-11-22
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
  • 2011-06-05
  • 2020-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多