【问题标题】:NSFetchedResultsController only updating with deletion of objects but not with insertionsNSFetchedResultsController 仅通过删除对象而不是插入进行更新
【发布时间】:2011-09-16 06:13:26
【问题描述】:

我有一个 NSFetchedResultsController,它基本上更新 UITableView,其中包含在后台更新的对象列表 NSOperation 实例化/更新了来自 Web 服务的 API 调用。我已经使用来自该站点的代码实现了各种 NSFetchedResultsControllerDelegate 方法(例如controllerWillChangeContentcontroller:didChangeObject:atIndexPath:forChangeType:newIndexPath 等):http://www.raywenderlich.com/999/core-data-tutorial-how-to-use-nsfetchedresultscontroller

问题是当插入与谓词匹配的对象时,永远不会在 UITableView 中插入一行。但是,当我删除表视图中已经显示的对象时,其对应的行会正确消失。

下面是实例化 NSFetchedResultsController 的代码:

 - (NSFetchedResultsController *)fetchedResultsController
{
    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

    // is a nearby category of objects - check to see if passed in
    if (self.nearbyCat == nil) return nil;

    // Creates a new NSManagedObjectContext
    NSManagedObjectContext *moContext = [[Utils getUtils] newManagedObjectContext];
    NSFetchRequest *req = [[NSFetchRequest alloc] init];
    NSEntityDescription *nearbyObjDesc = [NSEntityDescription entityForName:ENTITY_NAME_OBJECT inManagedObjectContext:moContext];
    [req setEntity:nearbyObjDesc];

    // predicate key path is passed into the view controller is an ivar - fetchKeyPath
    NSString *predKeyPath = self.fetchKeyPath;
    NSString *catName = [self.nearbyCat valueForKey:kCategoryNameKey];

    NSPredicate *pred = [NSPredicate predicateWithFormat:@"(%K like %@)", 
                         predKeyPath, catName];
    [req setPredicate:pred];
    [predKeyPath release];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:kObjectScoreKey ascending:NO];
    [req setSortDescriptors:[NSArray arrayWithObject:sort]];
    [req setFetchBatchSize:20];

    _cacheName = [[NSString alloc] initWithFormat:@"NearbyObjectsFor%@", catName];

    // In case there are new objects created because of change in location, 
    // we delete from the cache first, keeping the cache fresh.
    [NSFetchedResultsController deleteCacheWithName:_cacheName];

    NSFetchedResultsController *myFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:req managedObjectContext:moContext sectionNameKeyPath:nil cacheName:_cacheName];
    [moContext release];

    self.fetchedResultsController = myFetchedResultsController;
    _fetchedResultsController.delegate = self;

    [sort release];
    [req release];
    [myFetchedResultsController release];

    return _fetchedResultsController;
}

我使用推荐的方法注册 NSManagedObjectContextDidSaveNotification 然后在下面的方法 mergeContextChanges 的主线程上执行 mergeChangesFromContextDidSaveNotification::

- (void)mergeContextChanges:(NSNotification *)note 
{ 
    if(note.object && self.fetchedResultsController)
    {

        SEL selector = @selector(mergeChangesFromContextDidSaveNotification:);
        [[self.fetchedResultsController managedObjectContext] performSelectorOnMainThread:selector withObject:note waitUntilDone:YES];
    }
}

以前有没有人遇到过类似的问题?

【问题讨论】:

  • 你说:“问题是......当我删除一个对象......”那么你的问题是删除还是插入?
  • 对不起应该更清楚。问题是当我插入表格视图时没有更新。

标签: objective-c ios uitableview core-data nsfetchedresultscontroller


【解决方案1】:

插入执行并保存成功后,调用

[self.tableView reloadData];

【讨论】:

  • 在模拟器上,删除后调用reloadData有清空整个UITableView的效果。在插入时,保存后,我在controller:didChangObject:atIndexPath:forChangeType:newIndexPath: 中得到一个 EXC_BAD_ACCESS。我的印象是使用 NSFetchedResultsController 你不必调用 reloadData。
  • 我通常首先将fetchedResultsController 设置为nil,以便在getter 中重新设置它。看看这是否有效。
  • 感谢您的帮助。我使用了与您的方法类似的方法,但出现了一些错误,可能是因为我的课程的编写方式。所以我对其进行了调整并在下面发布了解决方案。既然你启发了我,我会将你的解决方案标记为答案。
【解决方案2】:

我尝试了多种方法并决定选择 NSFetchedResultsController 对解决方案。我最初想要插入一行时的漂亮动画效果,但现在这似乎不行,所以我决定只重新加载整个表格。

基本上,我会监听从 Web 服务返回成功查询时发布的通知。然后我切换到另一个 NSFetchedResultsController 实例,执行获取并调用表更新方法。我看到了一些动画,但它适用于整个表格,而不仅仅是相关行;我认为这是在后台进行数据检索的一种妥协。

感谢您的帮助。

通知处理方法的一些伪代码:

method handleServiceRetrievalSuccess
    Get current fetched results controller, frcA
    Release frcA
    Instantiate new fetched results controller, frcB
    Set frcB as current fetched results controller
    frcB->performFetch
    Reload table view

【讨论】:

    猜你喜欢
    • 2015-10-19
    • 2015-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多