NSFetchedResultsController仅更新删除对象但不插入

时间:2011-09-16 06:13:26

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

我有一个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];
    }
}

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

2 个答案:

答案 0 :(得分:0)

插入执行并成功保存后,请致电

[self.tableView reloadData];

答案 1 :(得分:0)

我尝试了多种方法,并决定选择NSFetchedResultsController对解决方案。当插入一行时,我原本想要很好的动画效果,但现在看起来像是禁止的,所以我只是为了重新加载整个表而安顿下来。

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

感谢您的帮助。

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

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